n8n-io/n8n · warning

SDK_AS_CONST

SDK_AS_CONST

Error message

`as const` is TypeScript-only and the workflow parser cannot interpret it. Remove the assertion.

What it means

SDK_AS_CONST emitted from lintWorkflowSdkAst() is a lint issue. After a successful parse, each collected 'as const' match that is NOT inside a string/template literal range is flagged, because the workflow parser cannot interpret TS assertions. String-content matches (e.g. inside jsCode) are intentionally skipped via stringContentRanges().

Source

Thrown at packages/@n8n/workflow-sdk/src/lint/sdk/workflow-sdk-lint.ts:178

	if (line < range.startLine || line > range.endLine) return false;
	if (line === range.startLine && column < range.startColumn) return false;
	if (line === range.endLine && column >= range.endColumn) return false;
	return true;
}

/** Lint a prepared, parsed SDK AST (imports/TS already stripped). */
export function lintWorkflowSdkAst(
	ast: Program,
	asConstMatches: AsConstMatch[] = [],
): SourceLintIssue[] {
	const issues: SourceLintIssue[] = [];

	const stringRanges = stringContentRanges(ast);
	for (const match of asConstMatches) {
		if (stringRanges.some((range) => rangeContains(range, match.line, match.column))) continue;
		issues.push(
			lintIssue({
				code: 'SDK_AS_CONST',
				message:
					'`as const` is TypeScript-only and the workflow parser cannot interpret it. Remove the assertion.',
				line: match.line,
				column: match.column + 1,
				lintTarget: 'sdk',
			}),
		);
	}

	const exportIndex = ast.body.findIndex((stmt) => stmt.type === 'ExportDefaultDeclaration');
	if (exportIndex >= 0) {
		for (let i = exportIndex + 1; i < ast.body.length; i++) {
			const stmt = ast.body[i];
			if (!stmt || stmt.type === 'EmptyStatement') continue;
			issues.push(
				lintIssue({
					code: 'SDK_CODE_AFTER_EXPORT_DEFAULT',
					message:

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Delete the `as const` assertion — the literal value itself is enough.
  2. If you need a typed literal, keep it in a separate non-SDK TS module; the SDK source must stay assertion-free.
  3. Re-run lintWorkflowSource to confirm zero SDK_AS_CONST issues.

Example fix

// before
export default workflow()
  .addNode(httpRequest({
    parameters: { method: 'POST' as const },
  }));
// after
export default workflow()
  .addNode(httpRequest({
    parameters: { method: 'POST' },
  }));
Defensive patterns

Strategy: validation

Validate before calling

import { lintWorkflowSource } from '@n8n/workflow-sdk/lint/lint-workflow-source';
const issues = lintWorkflowSource(sdkSource);
if (issues.some((i) => i.code === 'SDK_AS_CONST')) {
  throw new Error('SDK source has `as const` outside strings; remove the assertion.');
}

Prevention

When it happens

Trigger: mode: 'runOnceForAllItems' as const, type: 'webhook' as const, or any `as const` assertion on a literal in SDK builder code outside of a string.

Common situations: Agent writes idiomatic TS literal narrowing; developer copies typed config from a TS file; assertion left over from a type-driven design.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/d3754756f27d49d4. Report an issue: GitHub.