oxc-project/oxc · error · OxcDiagnostic
Unexpected newline between function name and open parenthesi
Error message
Unexpected newline between function name and open parenthesis of function call
What it means
`no-unexpected-multiline` (the ASI rule) reports code where a newline makes the parser join two lines into one expression. This variant, `DiagnosticKind::FunctionCall`, fires when the next line starts with `(`: the previous statement's last expression is parsed as a function call. The label attaches to the open-paren span with "this is parsed as a function call, which may be unintentional" and the help suggests inserting `;` before the parenthesis.
Source
Thrown at crates/oxc_linter/src/rules/eslint/no_unexpected_multiline.rs:21
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{AstNode, context::LintContext, rule::Rule};
#[derive(Debug, Default, Clone)]
pub struct NoUnexpectedMultiline;
enum DiagnosticKind {
FunctionCall { open_paren_span: Span },
PropertyAccess { open_bracket_span: Span },
TaggedTemplate { backtick_span: Span },
Division { slash_span: Span },
}
fn no_unexpected_multiline_diagnostic(kind: &DiagnosticKind) -> OxcDiagnostic {
match kind {
DiagnosticKind::FunctionCall { open_paren_span } => OxcDiagnostic::warn(
"Unexpected newline between function name and open parenthesis of function call",
)
.with_label(
open_paren_span.label("this is parsed as a function call, which may be unintentional"),
)
.with_help(
"If you did not intend to make a function call, insert ';' before the parenthesis",
),
DiagnosticKind::PropertyAccess { open_bracket_span } => OxcDiagnostic::warn(
"Unexpected newline between object and open bracket of property access",
)
.with_label(
open_bracket_span
.label("this is parsed as a property access, which may be unintentional"),
)
.with_help("If you did not intend to access a property, insert ';' before the bracket"),
DiagnosticKind::TaggedTemplate { backtick_span } => {
OxcDiagnostic::warn(View on GitHub (pinned to e1e7af627c)
Solutions
- Add a semicolon at the end of the previous statement.
- Or start the risky line with a protective leading `;` (`;(function(){})()`).
- Long-term: adopt always-semicolon style (or run a formatter) so ASI joins cannot happen.
Example fix
// before const result = compute() (fn || defaultFn)() // after const result = compute(); (fn || defaultFn)();
Defensive patterns
Strategy: validation
Validate before calling
# heuristic: lines starting with '(' after a line ending in a word/paren
rg -n -U '[\w)\]]\s*\n\(\s*\S' src/ Prevention
- Use semicolons consistently; let a formatter insert them.
- In semicolon-less style, prefix '(' leading lines with ';'.
- Review any diff that moves an IIFE to the start of a line.
When it happens
Trigger: `const a = foo\n(function () {}())` — i.e. a statement ending in an identifier/literal/closing paren followed by a newline and a line starting with `(`. Classic with IIFEs and function calls split across lines in semicolon-less style.
Common situations: Semicolon-less codebases after concatenating files; a line starting with `(` after a `return`/assignment; refactors that move an IIFE or parenthesized expression onto its own line.
Related errors
- Unexpected newline between object and open bracket of proper
- Unexpected newline between template tag and template literal
- Unexpected newline between numerator and division operator
- Empty array binding pattern
- Empty object binding pattern
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/da2f03dfc342bfa5.
Report an issue: GitHub.