{"record":{"id":"7ed440ae360c6f6c","repo":"angular/angular-cli","slug":"invalid-target-string","errorCode":null,"errorMessage":"Invalid target string: ","messagePattern":"Invalid target string: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/architect/src/api.ts","lineNumber":343,"sourceCode":"/**\n * Returns a string of \"project:target[:configuration]\" for the target object.\n */\nexport function targetStringFromTarget({ project, target, configuration }: Target) {\n  return `${project}:${target}${configuration !== undefined ? ':' + configuration : ''}`;\n}\n\n/**\n * Return a Target tuple from a specifier string.\n * Supports abbreviated target specifiers (examples: `::`, `::development`, or `:build:production`).\n */\nexport function targetFromTargetString(\n  specifier: string,\n  abbreviatedProjectName?: string,\n  abbreviatedTargetName?: string,\n): Target {\n  const tuple = specifier.split(':', 3);\n  if (tuple.length < 2) {\n    throw new Error('Invalid target string: ' + JSON.stringify(specifier));\n  }\n\n  return {\n    project: tuple[0] || abbreviatedProjectName || '',\n    target: tuple[1] || abbreviatedTargetName || '',\n    ...(tuple[2] !== undefined && { configuration: tuple[2] }),\n  };\n}\n\n/**\n * Schedule a target, and forget about its run. This will return an observable of outputs, that\n * as a teardown will stop the target from running. This means that the Run object this returns\n * should not be shared.\n *\n * The reason this is not part of the Context interface is to keep the Context as normal form as\n * possible. This is really an utility that people would implement in their project.\n *\n * @param context The context of your current execution.","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/architect/src/api.ts#L325-L361","documentation":"targetFromTargetString parses a 'project[:target[:configuration]]' specifier. It throws when the string doesn't contain at least one colon, i.e. it cannot yield a project and target pair.","triggerScenarios":"Calling targetFromTargetString('my-app') or targetFromTargetString('') — a string whose split(':') produces fewer than 2 segments.","commonSituations":"Passing a bare project name from CLI args or config instead of a project:target pair; typos like 'app-' or 'app::'; reading a target name from env vars that are unset or malformed.","solutions":["Pass a full specifier like 'my-app:build' (or 'my-app:build:production')","Trim/sanitize the input string before calling (strip stray colons/whitespace)","For project-only input, resolve the default target yourself via the architect host before converting"],"exampleFix":"// before\nconst target = targetFromTargetString(process.env.TARGET);\n// after\nconst spec = process.env.TARGET;\nif (!spec || !spec.includes(':')) throw new Error('TARGET must be like project:target');\nconst target = targetFromTargetString(spec);","handlingStrategy":"validation","validationCode":"function isValidTargetSpecifier(s) {\n  return typeof s === 'string' && /^[^:]+:[^:]+(:[^:]+)?$/.test(s);\n}\nif (!isValidTargetSpecifier(spec)) throw new Error(`Not a target specifier: ${spec}`);","typeGuard":"function isTargetLike(v) {\n  return typeof v === 'string' && v.split(':').filter(Boolean).length >= 2;\n}","tryCatchPattern":"try {\n  const target = targetFromTargetString(spec);\n} catch (e) {\n  if (e.message.startsWith('Invalid target string')) {\n    console.error(`\"${spec}\" must look like project:target[:configuration]`);\n  }\n  throw e;\n}","preventionTips":["Validate CLI/config-provided specifiers against /^[^:]+:[^:]+(:[^:]+)?$/ before use","Fail early with a clear message when a bare project name is supplied","Avoid building target strings via naive concatenation; use a helper"],"tags":["angular","architect","target-string","argument-parsing"],"backgroundTag":"invalid-target-string","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}