{"record":{"id":"a66fe2dc67ead6c5","repo":"languagetool-org/languagetool","slug":"text-cannot-be-used-with-interpretas-only-ma","errorCode":null,"errorMessage":"'text' cannot be used with 'interpretAs' (only 'markup' can): ","messagePattern":"'text' cannot be used with 'interpretAs' \\(only 'markup' can\\): ","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"languagetool-server/src/main/java/org/languagetool/server/ApiV2.java","lineNumber":486,"sourceCode":"    }\n    return textBuilder.build();\n  }\n\n  private AnnotatedText getAnnotatedTextFromJson(JsonNode data) {\n    AnnotatedTextBuilder atb = new AnnotatedTextBuilder();\n    // Expected format:\n    // annotation: [\n    //   {text: 'text'},\n    //   {markup: '<b>'}\n    //   {text: 'more text'},\n    //   {markup: '</b>'}\n    // ]\n    //\n    for (JsonNode node : data.get(\"annotation\")) {\n      if (node.get(\"text\") != null && node.get(\"markup\") != null) {\n        throw new BadRequestException(\"Only either 'text' or 'markup' are supported in an object in 'annotation' list, not both: \" + node);\n      } else if (node.get(\"text\") != null && node.get(\"interpretAs\") != null) {\n        throw new BadRequestException(\"'text' cannot be used with 'interpretAs' (only 'markup' can): \" + node);\n      } else if (node.get(\"text\") != null) {\n        atb.addText(node.get(\"text\").asText());\n      } else if (node.get(\"markup\") != null) {\n        if (node.get(\"interpretAs\") != null) {\n          atb.addMarkup(node.get(\"markup\").asText(), node.get(\"interpretAs\").asText());\n        } else {\n          atb.addMarkup(node.get(\"markup\").asText());\n        }\n      } else {\n        throw new BadRequestException(\"Only 'text' and 'markup' are supported in 'annotation' list: \" + node);\n      }\n    }\n    return atb.build();\n  }\n\n  String getLanguages() throws IOException {\n    StringWriter sw = new StringWriter();\n    try (JsonGenerator g = factory.createGenerator(sw)) {","sourceCodeStart":468,"sourceCodeEnd":504,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/ApiV2.java#L468-L504","documentation":"In the 'annotation' list of the /v2/check data parameter, 'interpretAs' is only allowed together with 'markup'. If an object has both 'text' and 'interpretAs', LanguageTool throws BadRequestException because there is no meaningful way to reinterpret explicit text.","triggerScenarios":"POSTing data like {\"annotation\":[{\"text\":\"Hello\",\"interpretAs\":\"Hi\"}]} — a node with both non-null 'text' and 'interpretAs' keys (and no 'markup').","commonSituations":"Copying the markup+interpretAs pattern onto text objects; template-based payload builders that always emit interpretAs.","solutions":["Remove 'interpretAs' from text objects.","If reinterpretation is needed, convert the entry to {\"markup\":\"...\",\"interpretAs\":\"...\"}.","Validate the annotation JSON client-side before sending."],"exampleFix":"// before\n{\"annotation\":[{\"text\":\"gr8\",\"interpretAs\":\"great\"}]}\n// after\n{\"annotation\":[{\"markup\":\"gr8\",\"interpretAs\":\"great\"}]}","handlingStrategy":"validation","validationCode":"for (const n of annotation) {\n  if (n.text != null && n.interpretAs != null) throw new Error('interpretAs is only valid with markup: ' + JSON.stringify(n));\n}","typeGuard":"function canUseInterpretAs(n) { return n.markup != null || n.interpretAs == null; }","tryCatchPattern":"try {\n  const res = await fetch('/v2/check', { method: 'POST', body: form });\n  if (res.status === 400) throw new Error(await res.text());\n} catch (e) {\n  console.error('annotation payload invalid:', e.message);\n}","preventionTips":["Only emit interpretAs next to markup.","Strip interpretAs from text nodes in your payload builder.","Add a unit test for annotation payload generation."],"tags":["http","api","json","validation","languagetool"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}