Invalid UTF-8 JSON on CouchDB bulk document api

I have a node console app where I am trying to post a number of record to the bulk document api on a local CouchDB instance and getting an "Invalid UTF-8 JSON." What makes this particularly odd, is that I'm generating my JSON using JSON.stringify on a object literal.

I tested the actual json at http://jsonlint.com/ and supposedly it's valid. I can't post the full json here as it's names and number from a directory, but I can show you a mock record to give you the basic structure.

{
 "family" : "Smith",
        "people":{
            "Bob":{
                 "name":"Bob", 
                 "active" : true,
                "birthday" : "1/01"
            },
            "Sue":{
                "name": "Sue", 
                "active" : true,
                "birthday" : "1/01"
            }
        },
        "address": {
            "street" :"1111 Cool Road",
            "city" : "Cincinnati",
            "state" : "OH",
            "zip" : "11111"
        },
        "phone" : "923-4908"            
};

I wrapped my array of records in a json object with the property "docs" as specified here. Is there anything obviously wrong with what I'm trying to do?

UPDATE: Following lambmj's suggestion, I wrote the string generated by node out to a file and then used curl to post that to the bulk document upload. That worked perfectly. I'd still like someone to help me correct my node code though, so that it works from within node. Here's the exact code that builds and posts the request

  //The result variable is my array of 'family' objects, 
  //It's generated by parsing a text file, not show here
  var postOptions = {
  host: 'localhost',
  port: '5984',
  path: '/members/_bulk_docs',
  method: 'POST',
  headers: {
      'Content-Type': 'application/json',
      'Content-Length': result.length
  }
};
var request = http.request(postOptions, function(res){
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      console.log('Response: ' + chunk);
    });
});
var body = { "docs": result};
var stringData = JSON.stringify(body);
console.log(stringData);
request.write(stringData);

I was able to get your example to work using the following command:

curl -X POST -H "Content-type:application/json" \
    http://localhost:5984/test/_bulk_docs -d @family.json

where family.json contains the following. I added a second family so that there would more than one element in the array.

{"docs": [
  {"family" : "Smith",
    "people":{
        "Bob":{
             "name":"Bob", 
             "active" : true,
            "birthday" : "1/01"
        },
        "Sue":{
            "name": "Sue", 
            "active" : true,
            "birthday" : "1/01"
        }
    },
    "address": {
        "street" :"1111 Cool Road",
        "city" : "Cincinnati",
        "state" : "OH",
        "zip" : "11111"
    },
    "phone" : "923-4908"
  },
  {"family" : "Jones",
    "people":{
        "John":{
             "name":"John",
             "active" : true,
            "birthday" : "1/01"
        },
        "Mary":{
            "name": "Mary",
            "active" : true,
            "birthday" : "1/01"
        }
    },
    "address": {
        "street" :"1112 Cool Road",
        "city" : "Cincinnati",
        "state" : "OH",
        "zip" : "11111"
    },
    "phone" : "923-4909"
  }
]}

The JSON is the same as provided wrapped in an array and provided as the value for docs attribute of the JSON passed to CouchDB. Also there's a trailing semi-colon (;) in the example you gave. That might be the problem if everything else is formatted correctly.

UPDATE:

OK, here's the answer node code. I made 3 changes as noted in the code:

#!/usr/bin/env node

var http = require("http");

// Embedding the family object here so that this test program will compile/run.

result = {
     "family" : "Smith",
            "people":{
                "Bob":{
                     "name":"Bob",
                     "active" : true,
                    "birthday" : "1/01"
                },
                "Sue":{
                    "name": "Sue",
                    "active" : true,
                    "birthday" : "1/01"
                }
            },
            "address": {
                "street" :"1111 Cool Road",
                "city" : "Cincinnati",
                "state" : "OH",
                "zip" : "11111"
            },
            "phone" : "923-4908"        
    };

var body = { "docs": [result]};                 // Change #1: docs takes an array.

var stringData = JSON.stringify(body);          // Change #2: stringify first.

var postOptions = {
  host: 'localhost',
  port: '5984',
  path: '/members/_bulk_docs',
  method: 'POST',
  headers: {
      'Content-Type': 'application/json',
      'Content-Length': stringData.length       // Change #3: send the length of the stringified data.
  }
};

var request = http.request(postOptions, function(res){
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      console.log('Response: ' + chunk);
    });
});

console.log(stringData);

request.write(stringData);

request.end();

Here's the output I get from node:

{"docs":[{"family":"Smith","people":{"Bob":{"name":"Bob","active":true,"birthday":"1/01"},"Sue":{"name":"Sue","active":true,"birthday":"1/01"}},"address":{"street":"1111 Cool Road","city":"Cincinnati","state":"OH","zip":"11111"},"phone":"923-4908"}]}

Response: [{"ok":true,"id":"721b8cde7a1e22b4cc106adbb3f41df9","rev":"1-306b71ff83df48c588a174fd5feafa34"}]