beppu/anyevent-couchdb — Issue #7: Couch 412 error "missing_stub" on saving document with attachment which was previously uploaded as inline attachment
Author: tungj
Created: 2012-01-18 18:04:50+00:00
State: open

If you save a document with an inline attachment, the changes from 1.26 lib/AnyEvent/CouchDB/Database.pm
delete the 'data' property and replace it with length, revpos, and stub:true.

Since revpos is extracted with a regex, it's in string context. The next time you save the document, the revpos in the attachment stub is sent to the server as a string. Unfortunately, on couchdb 1.1.1, this causes an error 412 since CouchDB expects revpos to be a number, and gives a ```{"error":"missing_stub","reason":"id:test, name:test3.gif"}``` response.

e.g. with a document with a 'test3.gif' attachment uploaded at revpos 2, ```curl -X PUT localhost:5984/database/test -d '{"_id":"test",
"_rev":"14-47afaef5d143f63a9f9104e90c1ce71a",
"_attachments":{"test3.gif":{"revpos":"2","length":6,"stub":true}}}'``` fails, but ```curl -X PUT localhost:5984/database/test -d '{"_id":"test",
"_rev":"14-47afaef5d143f63a9f9104e90c1ce71a",
"_attachments":{"test3.gif":{"revpos":2,"length":6,"stub":true}}}'``` works.

One possible solution is to use revpos in a numeric context before saving so it'll be serialized as a number, the other solution is to just delete it before sending since CouchDB seems happy to accept {stub:true}.

Incidentally, CouchDB 1.1.1 adds an MD5 'digest' field to the returned stub; it can be left out when saving the document though as long as {stub:true} is present.