usebruno/bruno · error · Error
Failed to parse ${context}: ${error.message}
Error message
Failed to parse ${context}: ${error.message} What it means
Thrown by safeJsonParse when JSON.parse fails on a string passed into the gRPC client (message content, request body, response metadata). The helper wraps the raw parse error with the context label and also console.errors the original string and parse error before re-throwing.
Source
Thrown at packages/bruno-requests/src/grpc/grpc-client.js:67
return data;
}
return Buffer.from(data, 'utf-8');
};
/**
* Safely parse JSON string with error handling
* @param {string} jsonString - The JSON string to parse
* @param {string} context - Context for error messages (e.g., 'message content', 'request body')
* @returns {Object} Parsed object or throws error with context
* @throws {Error} If JSON parsing fails
*/
const safeJsonParse = (jsonString, context = 'JSON string') => {
try {
return JSON.parse(jsonString);
} catch (error) {
const errorMessage = `Failed to parse ${context}: ${error.message}`;
console.error(errorMessage, { originalString: jsonString, parseError: error });
throw new Error(errorMessage);
}
};
const processGrpcMetadata = (metadata) => {
return Object.entries(metadata).map(([name, value]) => {
if (Array.isArray(value)) {
return {
name,
value: value
.map((v) => {
if (v && typeof v === 'object' && v.type === 'Buffer' && Array.isArray(v.data)) {
return Buffer.from(v.data).toString('base64');
}
return v.toString();
})
.join(', ')
};
}View on GitHub (pinned to 9bdd81c7bd)
Solutions
- Validate the JSON in the request body with a linter before sending.
- If the field is genuinely plain text, do not route it through the JSON parser — check the proto definition for the field type.
- Catch the error and surface the original string (already logged to console) to locate the syntax error.
- For streaming, ensure you are not feeding the parser half a buffered message.
Example fix
// before — body field contains malformed JSON
client.invoke('/pkg.Svc/Method', { body: "{name: 'abc'}" }); // unquoted key, single quotes
// after
client.invoke('/pkg.Svc/Method', { body: JSON.stringify({ name: 'abc' }) }); Defensive patterns
Strategy: try-catch
Validate before calling
function safeJsonParseLocal(s, ctx='JSON string') {
try { return JSON.parse(s); }
catch (e) { throw new Error(`Failed to parse ${ctx}: ${e.message}`); }
}
// pre-validate user-supplied body before sending to the gRPC client
if (typeof body === 'string') safeJsonParseLocal(body, 'request body'); Type guard
function isJsonString(s) {
if (typeof s !== 'string') return false;
try { JSON.parse(s); return true; } catch { return false; }
} Try / catch
try { client.invoke(path, { body }); }
catch (e) {
if (e.message.startsWith('Failed to parse')) { /* show original string, fix JSON */ }
else throw e;
} Prevention
- Run request bodies through a JSON validator in the UI before send.
- For text-typed proto fields, do not mark them as JSON.
- When streaming, buffer complete messages before parsing.
When it happens
Trigger: Invoking a gRPC method whose message body or metadata value is declared/passed as JSON but contains malformed JSON — unclosed braces, single quotes, trailing commas, or non-JSON plain text in a field the client tries to parse.
Common situations: User typed a request body in the Bruno gRPC UI that isn't valid JSON; protobuf JSON representation uses a field the user formatted incorrectly (e.g. Int64Value, Timestamp); a streaming message chunk was truncated mid-payload.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to minify
- Invalid environment: expected an object
- Invalid environment: missing or invalid variables array
- Invalid variable at index ${index}: expected an object
- Invalid variable at index ${index}: missing or invalid name
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/97478ea1313dd1c6.
Report an issue: GitHub.