oxc-project/oxc · info · OxcDiagnostic

Unexpected string concatenation.

Error message

Unexpected string concatenation.

What it means

oxlint `eslint/prefer-template`: a binary `+` expression involving strings was flagged ('Unexpected string concatenation.') and the rule wants template literals instead. The diagnostic at prefer_template.rs:12 fires from `prefer_template_diagnostic` when the visitor sees string-typed concatenation in a BinaryExpression. Template literals avoid operator-precedence bugs and read better when interpolating values.

Source

Thrown at crates/oxc_linter/src/rules/eslint/prefer_template.rs:12

use oxc_ast::{
    AstKind,
    ast::{BinaryExpression, BinaryOperator, Expression},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};

use crate::{AstNode, context::LintContext, fixer::RuleFixer, rule::Rule};

fn prefer_template_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Unexpected string concatenation.")
        .with_help("Use template literals instead of string concatenation.")
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct PreferTemplate;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Require template literals instead of string concatenation.
    ///
    /// ### Why is this bad?
    ///
    /// In ES2015 (ES6), we can use template literals instead of string concatenation.
    ///
    /// ### Examples
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Convert to a template literal: `"Hello " + name` becomes `` `Hello ${name}` ``.
  2. For long chains, combine into one template literal rather than nested concatenation.
  3. If concatenation is intentional (hot-path micro-optimization, or numeric operands), add `// oxlint-disable-next-line prefer-template`.
  4. Turn the rule off in `.oxlintrc.json` if the team prefers `+`.

Example fix

// before
const msg = "User " + user.name + " has " + user.points + " points";

// after
const msg = `User ${user.name} has ${user.points} points`;
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: `"Hello " + name`, `` `total: ` + count ``, or chained concatenation `a + " " + b` where at least one operand is a string literal — especially inside loops or when the rule sees dynamic values joined with strings.

Common situations: Message/URL/log builders written pre-ES6; JSX-adjacent string assembly; teams that enable prefer-template in a shared config and legacy code suddenly fails CI.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/9f3cef294592c969. Report an issue: GitHub.