zeroclaw-labs/zeroclaw · error · anyhow::Error

AIEOS payload must be a JSON object

Error message

AIEOS payload must be a JSON object

What it means

parse_aieos_identity runs serde_json::from_str on the AIEOS document and then requires the top-level value to be a JSON object. Valid JSON whose root is an array, string, number, or boolean is rejected because normalize_aieos_identity reads named sections (identity, psychology, linguistics, ...) off an object map. The preceding context "Invalid AIEOS JSON" covers syntactic failures; this bail covers shape failures.

Source

Thrown at crates/zeroclaw-runtime/src/identity.rs:215

        "Identity format is set to 'aieos' but neither aieos_path nor aieos_inline is configured. \
         Set one in your config:\n\
         \n\
         [identity]\n\
         format = \"aieos\"\n\
         aieos_path = \"identity.json\"\n\
         \n\
         Or use inline:\n\
         \n\
         [identity]\n\
         format = \"aieos\"\n\
         aieos_inline = '{{\"identity\": {{...}}}}'"
    )
}

fn parse_aieos_identity(content: &str) -> Result<AieosIdentity> {
    let payload: Value = serde_json::from_str(content).context("Invalid AIEOS JSON")?;
    if !payload.is_object() {
        anyhow::bail!("AIEOS payload must be a JSON object")
    }
    Ok(normalize_aieos_identity(&payload))
}

fn normalize_aieos_identity(payload: &Value) -> AieosIdentity {
    AieosIdentity {
        identity: normalize_identity_section(value_at_path(payload, &["identity"])),
        psychology: normalize_psychology_section(value_at_path(payload, &["psychology"])),
        linguistics: normalize_linguistics_section(value_at_path(payload, &["linguistics"])),
        motivations: normalize_motivations_section(value_at_path(payload, &["motivations"])),
        capabilities: normalize_capabilities_section(value_at_path(payload, &["capabilities"])),
        physicality: normalize_physicality_section(value_at_path(payload, &["physicality"])),
        history: normalize_history_section(value_at_path(payload, &["history"])),
        interests: normalize_interests_section(value_at_path(payload, &["interests"])),
    }
}

fn normalize_identity_section(section: Option<&Value>) -> Option<IdentitySection> {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Make the document root an object: {"identity": {...}, "psychology": {...}, ...}
  2. If the payload is double-encoded, decode one layer so the root is an object, not a quoted string
  3. Validate before running: jq -e 'type == "object"' identity.json exits non-zero for wrong shapes
  4. If exporting from a generator, pick the single-persona object output mode, not the list export

Example fix

// before (identity.json)
[{ "identity": { "name": "Claw" } }]

// after
{ "identity": { "name": "Claw" } }
Defensive patterns

Strategy: validation

Validate before calling

let parsed: serde_json::Value = serde_json::from_str(&content)
    .context("Invalid AIEOS JSON")?;
if !parsed.is_object() {
    anyhow::bail!("AIEOS payload must be a JSON object");
}

Type guard

fn is_aieos_payload(v: &serde_json::Value) -> bool {
    v.is_object()
}

Try / catch

match parse_aieos_identity(&content) {
    Ok(id) => id,
    Err(e) if e.to_string().contains("must be a JSON object") => {
        // shape problem: fix the document (root must be an object), do not retry as-is
    }
    Err(e) => return Err(e), // e.g. "Invalid AIEOS JSON" context — syntax problem
}

Prevention

When it happens

Trigger: aieos_path points at a file like [{"identity": ...}] (root array) or "just a string"; aieos_inline is double-encoded — a JSON string containing JSON ("{"identity": ...}"), so the root parses as a string; a generator exported a bare array of personas instead of a single object.

Common situations: Hand-editing identity.json and wrapping it in brackets; passing a JSONL/array export where one object is expected; serializing with an extra json!()/to_string() layer before storing into aieos_inline; jq output of `.[0]` style queries leaving array roots.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/af898f7adf96b892. Report an issue: GitHub.