{"record":{"id":"de52884edc518424","repo":"angular/angular-cli","slug":"expected-a-jobhandler-as-second-argument","errorCode":null,"errorMessage":"Expected a JobHandler as second argument.","messagePattern":"Expected a JobHandler as second argument\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/architect/src/jobs/simple-registry.ts","lineNumber":76,"sourceCode":"   * @param handler The function that will be called for the job.\n   * @param options An optional list of options to override the handler. {@see RegisterJobOptions}\n   */\n  register<ArgumentT extends JsonValue, InputT extends JsonValue, OutputT extends JsonValue>(\n    handler: JobHandler<ArgumentT, InputT, OutputT>,\n    // This version MUST contain a name.\n    options?: RegisterJobOptions & { name: string },\n  ): void;\n\n  register<ArgumentT extends JsonValue, InputT extends JsonValue, OutputT extends JsonValue>(\n    nameOrHandler: JobName | JobHandler<ArgumentT, InputT, OutputT>,\n    handlerOrOptions: JobHandler<ArgumentT, InputT, OutputT> | RegisterJobOptions = {},\n    options: RegisterJobOptions = {},\n  ): void {\n    // Switch on the arguments.\n    if (typeof nameOrHandler == 'string') {\n      if (!isJobHandler(handlerOrOptions)) {\n        // This is an error.\n        throw new TypeError('Expected a JobHandler as second argument.');\n      }\n\n      this._register(nameOrHandler, handlerOrOptions, options);\n    } else if (isJobHandler(nameOrHandler)) {\n      if (typeof handlerOrOptions !== 'object') {\n        // This is an error.\n        throw new TypeError('Expected an object options as second argument.');\n      }\n\n      const name = options.name || nameOrHandler.jobDescription.name || handlerOrOptions.name;\n      if (name === undefined) {\n        throw new TypeError('Expected name to be a string.');\n      }\n\n      this._register(name, nameOrHandler, options);\n    } else {\n      throw new TypeError('Unrecognized arguments.');\n    }","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/architect/src/jobs/simple-registry.ts#L58-L94","documentation":"SimpleJobRegistry.register() accepts either a job name string plus a handler, or a bare JobHandler object. When the first argument is a string, the second argument must be a valid JobHandler; this TypeError is thrown when isJobHandler(handlerOrOptions) fails, i.e. the second argument is not a function/object with the expected job-handler shape.","triggerScenarios":"Calling registry.register('job-name', <something that is not a JobHandler>) — e.g. passing the wrong variable, a plain function missing jobDescription/argument/input/output properties, or passing the options object as the second argument by mistake.","commonSituations":"Passing arguments in the wrong order (name, options, handler) instead of (name, handler, options); passing a plain callback from an older job API after an Angular DevKit version change; refactoring that replaced a handler with a factory return value.","solutions":["Pass a valid JobHandler (created via createJobHandler) as the second argument: registry.register('my-job', createJobHandler(() => ..., { name: 'my-job' })).","Check argument order: register(name, handler, options) — swap the second and third arguments if an options object was passed second.","If registering a bare handler, drop the string and call register(handler) or register(handler, { name: 'my-job' }) so the name is inferred from jobDescription.name.","Log or inspect the second argument's type just before the call to confirm it is the handler, not a Promise resolving to one (await it first)."],"exampleFix":"// before\nregistry.register('build-job', { name: 'build-job', description: 'build' });\n// after\nregistry.register('build-job', createJobHandler(() => of({ success: true }), { name: 'build-job', description: 'build' }));","handlingStrategy":"type-guard","validationCode":"const { isJobHandler } = require('@angular-devkit/architect');\nif (typeof nameOrHandler === 'string' && !isJobHandler(handlerOrOptions)) {\n  throw new Error('second argument must be a JobHandler');\n}","typeGuard":"function isHandler(v) {\n  return v != null && (typeof v === 'function' || (typeof v === 'object' && typeof v.handler === 'function' && v.jobDescription && typeof v.jobDescription.name === 'string'));\n}","tryCatchPattern":"try {\n  registry.register(name, handler);\n} catch (e) {\n  if (e instanceof TypeError && /JobHandler as second argument/.test(e.message)) {\n    throw new Error(`register('${name}') got a non-handler second argument: ${typeof handler}`);\n  }\n  throw e;\n}","preventionTips":["Always create handlers with createJobHandler rather than plain functions","Keep argument order (name, handler, options) consistent; consider using the handler-only form with options.name","Check isJobHandler(x) in unit tests before registering","Beware of Promises: await handler factories before calling register"],"tags":["typescript","typeerror","architect","job-registry","wrong-arguments"],"backgroundTag":"invalid-argument-type","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}