{"record":{"id":"e89257435fd089b6","repo":"JetBrains/intellij-community","slug":"cannot-handle-content-change-for-e89257","errorCode":null,"errorMessage":"cannot handle content change for: ","messagePattern":"cannot handle content change for: ","errorType":"exception","errorClass":"IncorrectOperationException","httpStatus":null,"severity":"error","filePath":"java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/StringLiteralManipulator.java","lineNumber":32,"sourceCode":"import com.intellij.psi.util.PsiLiteralUtil;\nimport com.intellij.util.IncorrectOperationException;\nimport org.jetbrains.annotations.NotNull;\n\npublic final class StringLiteralManipulator extends AbstractElementManipulator<PsiLiteralExpression> {\n  @Override\n  public PsiLiteralExpression handleContentChange(@NotNull PsiLiteralExpression expr, @NotNull TextRange range, String newContent) throws IncorrectOperationException {\n    String oldText = expr.getText();\n    if (expr.isTextBlock()) {\n      newContent = escapeTextBlockContent(newContent);\n    }\n    else if (oldText.startsWith(\"\\\"\")) {\n      newContent = StringUtil.escapeStringCharacters(newContent);\n    }\n    else if (oldText.startsWith(\"'\") && newContent.length() <= 1) {\n      newContent = newContent.length() == 1 && newContent.charAt(0) == '\\''? \"\\\\'\" : newContent;\n    }\n    else {\n      throw new IncorrectOperationException(\"cannot handle content change for: \" + oldText + \", expr: \" + expr);\n    }\n\n    String newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset());\n    final PsiExpression newExpr = JavaPsiFacade.getElementFactory(expr.getProject()).createExpressionFromText(newText, null);\n    return (PsiLiteralExpression)expr.replace(newExpr);\n  }\n\n  private static @NotNull String escapeTextBlockContent(@NotNull String content) {\n    String[] lines = PsiLiteralUtil.escapeTextBlockCharacters(content, false, true, false).split(\"(?<=\\n)\");\n    int indent = PsiLiteralUtil.getTextBlockIndent(lines, true, true);\n    if (indent != 0 && lines.length > 0 && !lines[lines.length - 1].endsWith(\"\\n\")) {\n      // append \\ + newline at the end of the last line, so we can use closing \"\"\" to indent;\n      lines[lines.length - 1] += \"\\\\\\n\";\n    }\n    for (int i = 0; i < lines.length - 1; i++) {\n      String line = lines[i];\n      if (line.endsWith(\"\\\\\\n\") && lines[i + 1].equals(\"\\n\")) {\n        lines[i] = line.substring(0, line.length() - 2); // normalize strings with leading newlines","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/JetBrains/intellij-community/blob/be881553f2a76ac8b4ea53950d93f0de78295c19/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/StringLiteralManipulator.java#L14-L50","documentation":"StringLiteralManipulator.handleContentChange rewrites the value of a PsiLiteralExpression (string or char literal). It escapes content for text blocks and '\"'-delimited strings, and allows at most one character for \"'\"-delimited char literals. Any other combination — no leading quote, or multi-character content in a char literal — throws IncorrectOperationException(\"cannot handle content change for: ...\").","triggerScenarios":"Calling ElementManipulators.handleContentChange(literal, newContent) on a char literal with newContent.length() > 1, or on a PsiLiteralExpression whose text lacks quotes (broken PSI after failed parsing, or non-literal expressions misreported as literals).","commonSituations":"Intention 'replace string with char' style edits feeding multi-char text; language injection rewriters that call the manipulator generically on all literal expressions; unit tests mutating literals with arbitrary strings.","solutions":["Validate before editing: if literal text starts with \"'\" ensure newContent.length() <= 1 (escape the single quote via \"\\\\'\" as the manipulator does).","For multi-character content, convert the char literal to a string literal first (replace with '\"'-quoted expression), then apply the content change.","If the literal's text has no quotes, repair the PSI (reparse) before manipulating, or replace the element wholesale via PsiElementFactory."],"exampleFix":"// before\nElementManipulators.handleContentChange(charLiteral, \"ab\"); // char literal, 2 chars -> throws\n\n// after\nPsiExpression replacement = newContent.length() <= 1 && charLiteral.getText().startsWith(\"'\")\n    ? ElementManipulators.handleContentChange(charLiteral, newContent)\n    : (PsiExpression)charLiteral.replace(factory.createExpressionFromText(\"\\\"\" + StringUtil.escapeStringCharacters(newContent) + \"\\\"\", null));","handlingStrategy":"validation","validationCode":"String old = literal.getText();\nif (old.startsWith(\"'\") && newContent.length() > 1) return; // char literal cannot hold 2+ chars","typeGuard":null,"tryCatchPattern":"try { ElementManipulators.handleContentChange(literal, c); } catch (IncorrectOperationException e) { /* convert char to string literal first */ }","preventionTips":["Limit content to 1 char for char literals.","Convert char to string literal before inserting longer text."],"tags":["java","psi","literals","element-manipulator","escaping"],"backgroundTag":null,"analyzedSha":"be881553f2a76ac8b4ea53950d93f0de78295c19","analyzedAt":"2026-08-14T14:13:06.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}