OpenHands/OpenHands · warning
${field.label} must be a JSON object
Error message
${field.label} must be a JSON object What it means
Thrown by coerceFieldValue for an object settings field when JSON.parse succeeds but the parsed value is null, an array, or a non-object primitive. The field's value_type is 'object', so the top-level JSON must be a plain object (typeof === 'object', not null, not Array). Symmetric to error 56 for the object case.
Source
Thrown at src/utils/sdk-settings-schema.ts:397
try {
parsedValue = JSON.parse(stringValue);
} catch {
throw new Error(`Invalid JSON for ${field.label}`);
}
if (field.value_type === "array") {
if (!Array.isArray(parsedValue)) {
throw new Error(`${field.label} must be a JSON array`);
}
return parsedValue as SettingsValue[];
}
if (
parsedValue === null ||
Array.isArray(parsedValue) ||
typeof parsedValue !== "object"
) {
throw new Error(`${field.label} must be a JSON object`);
}
return parsedValue as { [key: string]: SettingsValue };
}
const stringValue = String(rawValue);
if (stringValue === "" && !field.secret) {
return null;
}
return stringValue;
}
export function buildSdkSettingsPayload(
schema: SettingsSchema,
values: SettingsFormValues,
dirty: SettingsDirtyState,
): SdkSettingsPayload {View on GitHub (pinned to 500b4c533e)
Solutions
- Enter a plain JSON object: '{ "key": value }'.
- To clear an object field, leave the input empty (the empty-string check returns null before JSON.parse).
- Confirm the field's value_type in /api/settings/agent-schema — if it is 'object', the top-level JSON must be a curly-braced object.
Example fix
// before
coerceFieldValue(objectField, '[1, 2, 3]'); // throws
// after
coerceFieldValue(objectField, '{ "a": 1 }'); // returns { a: 1 } Defensive patterns
Strategy: validation
Validate before calling
function isJsonObjectString(value: string): boolean {
try {
const parsed = JSON.parse(value);
return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed);
} catch { return false; }
}
// if (raw.trim() !== '' && !isJsonObjectString(raw)) showFieldError(field, 'Enter a JSON object'); Try / catch
try {
const coerced = coerceFieldValue(objectField, rawValue);
} catch (error) {
if (error instanceof Error && error.message.endsWith('must be a JSON object')) {
setFieldError(objectField.key, 'Top-level value must be a JSON object ({...})');
} else throw error;
} Prevention
- Confirm the field's value_type is 'object' before assuming array input is acceptable.
- Show a placeholder like '{ "key": value }' in object field inputs.
- To clear an object field, leave the input empty (empty string returns null) rather than entering 'null'.
When it happens
Trigger: User enters valid JSON that is not an object into an object-typed field — e.g. '[1,2,3]' (array), 'null', '"string"', or '42'. JSON.parse succeeds, the null/array/primitive check fails, guard throws.
Common situations: User enters an array where an object is expected; user enters 'null' expecting it to clear the field (empty string clears, not null); type confusion between object and array fields; user wraps the object in an array.
Related errors
- Invalid JSON for ${field.label}
- ${field.label} must be a JSON array
- Expected a boolean value, received: ${rawValue}
- Expected a numeric value, received: ${stringValue}
- Expected an integer value, received: ${stringValue}
AI-assisted analysis of OpenHands/OpenHands@500b4c533e (2026-08-12).
Data as JSON: /api/errors/57bc3eefb7056471.
Report an issue: GitHub.