# How to Handle Escaped JSON from Cohere Output in n8n

- Tool: n8n
- Difficulty: Advanced
- Time required: 15-20 minutes
- Compatibility: n8n 1.20+ with Cohere Chat Model sub-node
- Last updated: March 2026

## TL;DR

Cohere models sometimes return JSON with double-escaped characters — backslashes before quotes (\\\"key\\\" instead of \"key\"), escaped newlines (\\n), and Unicode escape sequences. Fix this by unescaping the string in a Code node before parsing, using the Structured Output Parser for automatic handling, and adjusting your Cohere prompt to request clean JSON output.

## Why Cohere Returns Escaped JSON in n8n

When Cohere models return JSON in n8n workflows, the output often contains double-escaped characters. This happens because Cohere's API serializes the response text as a JSON string value, which escapes special characters. When n8n then includes this in its own JSON data structure, the escaping can be doubled. For example, a quote (") becomes \" in the first serialization, then \\" in the second. Similarly, newlines (\n) become \\n. When you try to JSON.parse() this double-escaped string, it either fails with a syntax error or produces an object with literal backslash characters in the values. This issue is specific to how Cohere's response format interacts with n8n's data handling.

## Before you start

- A running n8n instance with Cohere API credentials configured
- A workflow using the Cohere Chat Model sub-node that requests JSON output
- Basic understanding of JSON escaping rules and n8n Code nodes

## Step-by-step guide

### 1. Inspect the Raw Cohere Output

Before fixing the issue, you need to see exactly what Cohere returns. Add a Code node after your LLM node and log the raw output. Look for patterns like: double backslashes before quotes (\\\"), escaped newlines as literal \\n characters, and Unicode escape sequences like \\u0022. Also check if the output is a string containing JSON (needs parsing) or already a parsed object (just needs unescaping of values). The inspection tells you which unescaping strategy to use.

```
const raw = $json.text || $json.output || $json.message?.content || '';

// Diagnostic output
return [{
  json: {
    raw_type: typeof raw,
    raw_length: raw.length,
    first_chars: raw.substring(0, 300),
    has_double_backslash: raw.includes('\\\\'),
    has_escaped_quotes: raw.includes('\\"'),
    has_literal_backslash_n: raw.includes('\\n'),
    starts_with_quote: raw.startsWith('"'),
    raw_output: raw
  }
}];
```

**Expected result:** You can see the exact escaping patterns in Cohere's output.

### 2. Unescape the Cohere Output in a Code Node

Add a Code node that systematically unescapes the Cohere output before parsing it as JSON. The function handles multiple layers of escaping that can occur depending on how the response passes through n8n's data pipeline. Set the Code node to 'Run Once for Each Item'. This function tries progressive unescaping until it finds valid JSON.

```
const raw = $json.text || $json.output || $json.message?.content || '';

function unescapeAndParse(text) {
  let str = text.trim();

  // If the entire output is wrapped in outer quotes, remove them
  if (str.startsWith('"') && str.endsWith('"')) {
    try {
      str = JSON.parse(str); // This unescapes one level
    } catch (e) {
      str = str.slice(1, -1);
    }
  }

  // Attempt 1: Direct parse
  try {
    return JSON.parse(str);
  } catch (e) {}

  // Attempt 2: Unescape double-escaped characters
  let unescaped = str
    .replace(/\\\\/g, '\\')        // \\\\ → \\
    .replace(/\\"/g, '"')          // \\" → "
    .replace(/\\n/g, '\n')         // \\n → newline
    .replace(/\\t/g, '\t')         // \\t → tab
    .replace(/\\r/g, '\r');        // \\r → return

  try {
    return JSON.parse(unescaped);
  } catch (e) {}

  // Attempt 3: Strip markdown fences then retry
  const fenceMatch = str.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);
  if (fenceMatch) {
    try {
      return JSON.parse(fenceMatch[1].trim());
    } catch (e) {}
  }

  // Attempt 4: Extract JSON object from surrounding text
  const jsonMatch = str.match(/\{[\s\S]*\}/);
  if (jsonMatch) {
    try {
      return JSON.parse(jsonMatch[0]);
    } catch (e) {}
  }

  return null;
}

const parsed = unescapeAndParse(raw);

if (parsed) {
  return [{ json: { data: parsed, parse_status: 'success' } }];
}

return [{ json: { raw_text: raw, parse_status: 'failed' } }];
```

**Expected result:** Double-escaped JSON from Cohere is correctly unescaped and parsed into a JavaScript object.

### 3. Use the Structured Output Parser with Cohere

The Structured Output Parser handles some escaping issues automatically because it instructs the model to return JSON in a specific format and then processes the output. Connect the Cohere Chat Model sub-node to an AI Agent or Basic LLM Chain, then add the Structured Output Parser. Define your schema. The parser adds formatting instructions to the prompt and handles initial parsing. For additional safety, also add the Auto-Fixing Output Parser.

**Expected result:** The Structured Output Parser handles Cohere's output formatting, reducing the need for manual unescaping.

### 4. Optimize Your Cohere Prompt for Clean JSON

Cohere's Command models respond well to explicit formatting instructions. Add specific directives to your system prompt that minimize escaping issues. Cohere's preamble parameter (available in the Cohere Chat Model sub-node) is particularly effective for this purpose — it acts as a system-level instruction that the model respects more consistently.

```
// Cohere preamble (system prompt) for clean JSON output:
const preamble = `You are a data extraction API.

RULES:
1. Return ONLY a single JSON object
2. Do not escape characters unnecessarily
3. Use standard double quotes for JSON keys and string values
4. Do not wrap the JSON in markdown code fences
5. Do not add explanatory text before or after
6. Do not double-escape special characters
7. Newlines in string values should be \\n (single escape)

The response MUST start with { and end with }

Output schema:
{"field1": "string", "field2": number, "items": ["array of strings"]}`;
```

**Expected result:** Cohere returns cleaner JSON with fewer escaping issues.

### 5. Handle Cohere-Specific Response Wrapper Fields

Cohere's API response includes additional metadata fields that other LLM APIs do not have, such as generation_id, citations, and search_results. When using the HTTP Request node to call Cohere directly, the JSON response you need is nested inside the response object. Extract the text field correctly before attempting to parse it as your structured data.

```
// When using HTTP Request node to call Cohere Chat API directly:
// The response structure is:
// {
//   "response_id": "...",
//   "text": "<your JSON output here>",
//   "generation_id": "...",
//   "chat_history": [...],
//   "finish_reason": "COMPLETE",
//   "meta": { "api_version": {...}, "billed_units": {...} }
// }

// Extract the text field which contains your actual LLM output
const cohereResponse = $json;
const llmOutput = cohereResponse.text || '';

// Now unescape and parse as shown in previous steps
let cleaned = llmOutput.trim();
if (cleaned.startsWith('"') && cleaned.endsWith('"')) {
  try { cleaned = JSON.parse(cleaned); } catch(e) { cleaned = cleaned.slice(1,-1); }
}

try {
  const data = JSON.parse(cleaned);
  return [{ json: { data, cohere_meta: cohereResponse.meta } }];
} catch (e) {
  return [{ json: { raw: llmOutput, parse_error: e.message } }];
}
```

**Expected result:** Cohere's response wrapper is handled correctly and the nested JSON output is extracted and parsed.

## Complete code example

File: `cohere-json-unescaper.js`

```javascript
// Code node: Run Once for Each Item
// Complete Cohere JSON unescaping and parsing pipeline

const raw = $json.text || $json.output || $json.message?.content || '';

function unescapeCohere(text) {
  if (!text || typeof text !== 'string') return null;
  let str = text.trim();

  // Step 1: Remove outer string quotes if present
  if ((str.startsWith('"') && str.endsWith('"')) ||
      (str.startsWith("'") && str.endsWith("'"))) {
    try {
      str = JSON.parse(str);
      if (typeof str !== 'string') return str; // Already parsed to object
    } catch (e) {
      str = str.slice(1, -1);
    }
  }

  // Step 2: Remove markdown fences
  const fenceMatch = str.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);
  if (fenceMatch) str = fenceMatch[1].trim();

  // Step 3: Try direct parse
  try { return JSON.parse(str); } catch (e) {}

  // Step 4: Fix double escaping
  const fixes = [
    [/\\\\"/g, '"'],          // \\" → "
    [/\\\\/g, '\\'],           // \\\\ → \\
    [/\\n/g, '\n'],            // Escaped newlines
    [/\\t/g, '\t'],            // Escaped tabs
    [/\\r/g, '\r'],            // Escaped returns
    [/\\u0022/g, '"'],         // Unicode quote escapes
    [/\\u0027/g, "'"],         // Unicode apostrophe
    [/\\\//g, '/']             // Escaped forward slashes
  ];

  let fixed = str;
  for (const [pattern, replacement] of fixes) {
    fixed = fixed.replace(pattern, replacement);
  }

  try { return JSON.parse(fixed); } catch (e) {}

  // Step 5: Extract JSON object from surrounding text
  const objectMatch = fixed.match(/\{[\s\S]*\}/);
  if (objectMatch) {
    try { return JSON.parse(objectMatch[0]); } catch (e) {}
  }

  // Step 6: Try one more level of unescaping
  try {
    const doubleUnescaped = JSON.parse('"' + fixed + '"');
    if (typeof doubleUnescaped === 'string') {
      return JSON.parse(doubleUnescaped);
    }
  } catch (e) {}

  return null;
}

const result = unescapeCohere(raw);

if (result !== null) {
  return [{
    json: {
      data: result,
      parse_status: 'success',
      source: 'cohere'
    }
  }];
}

return [{
  json: {
    raw_text: raw,
    parse_status: 'failed',
    source: 'cohere',
    suggestion: 'Check if the Cohere output format has changed or if the prompt needs adjustment'
  }
}];
```

## Common mistakes

- **Applying OpenAI/Claude JSON parsing logic to Cohere output without adapting for double escaping** — undefined Fix: Cohere's escaping patterns differ. Specifically handle double-escaped quotes (\\\") and escaped forward slashes (\/) which are uncommon in other LLM outputs.
- **Using string.replace() without the global flag, only fixing the first occurrence** — undefined Fix: Always use regex with the /g flag for replacements: str.replace(/\\\"/g, '"') instead of str.replace('\\"', '"').
- **Not handling the case where Cohere wraps the entire JSON string in outer quotes** — undefined Fix: Check if the output starts and ends with quotes. If so, use JSON.parse() on the whole string first to remove one escaping layer, then parse the inner string.
- **Assuming Cohere's response structure matches OpenAI's** — undefined Fix: Cohere's API response uses a 'text' field (not 'choices'). When using the HTTP Request node, extract $json.text, not $json.choices[0].message.content.

## Best practices

- Always add an unescaping Code node after Cohere LLM nodes — Cohere's escaping behavior differs from OpenAI and Claude
- Use the Structured Output Parser with Cohere to reduce but not eliminate escaping issues
- Include explicit 'do not double-escape' instructions in Cohere's preamble parameter
- Test your JSON parsing with various Cohere models (Command, Command-R) as they may escape differently
- Log raw Cohere output before unescaping during development to understand the exact patterns
- Use temperature 0 with Cohere when requesting JSON to minimize format variation
- Handle Unicode escape sequences (\u0022) alongside standard escaping patterns
- Set the Cohere response_format parameter to JSON when available in the API

## Frequently asked questions

### Why does Cohere double-escape JSON but OpenAI does not?

Cohere's API may serialize the model's text output as a JSON string value, which adds one layer of escaping. When n8n then includes this in its data pipeline as another JSON value, the escaping doubles. OpenAI's newer API versions handle this differently in their response serialization.

### Does this issue affect all Cohere models?

The escaping behavior can vary between Cohere model versions (Command, Command-R, Command-R+). Always test your unescaping code with the specific model you are using, and add logging to detect if the behavior changes after model updates.

### Can I avoid the escaping issue by using the HTTP Request node instead of the Cohere Chat Model sub-node?

Using the HTTP Request node gives you more control over response handling, but the underlying escaping comes from Cohere's API response format, not from n8n's node. You will still need to unescape, but you can process the response more precisely.

### What if the unescaped output is still not valid JSON?

If unescaping does not produce valid JSON, the model likely generated malformed JSON. Use the Auto-Fixing Output Parser to send the broken output back to Cohere with instructions to fix it, or restructure your prompt to request simpler output.

### Is there a Cohere API setting to prevent double escaping?

Cohere's API does not have a setting to control output escaping. The escaping occurs at the API response serialization level. Your best mitigation is prompt engineering (requesting raw JSON) combined with Code node unescaping.

### Can RapidDev help integrate Cohere with n8n for production use?

Yes. RapidDev can build n8n workflows with Cohere integration that handle all output formatting quirks, including escaped JSON, incomplete responses, and multi-turn conversation management.

---

Source: https://www.rapidevelopers.com/n8n-tutorial/how-to-handle-escaped-json-from-cohere-output-in-n8n
© RapidDev — https://www.rapidevelopers.com/n8n-tutorial/how-to-handle-escaped-json-from-cohere-output-in-n8n
