{"record":{"id":"7316a05bed696fb1","repo":"immich-app/immich","slug":"unknown-method-step-method","errorCode":null,"errorMessage":"Unknown method ${step.method}","messagePattern":"Unknown method (.+?)","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/workflow.service.ts","lineNumber":112,"sourceCode":"      result: entry.result,\n      triggerDataId: entry.triggerDataId ?? undefined,\n      lastStep: entry.step\n        ? {\n            index: entry.step.order,\n            method: `${entry.step.pluginId}#${entry.step.methodName}`,\n          }\n        : undefined,\n    }));\n  }\n\n  private async resolveAndValidateSteps<T extends { method: string }>(steps: T[], trigger: WorkflowTrigger) {\n    const methods = await this.pluginRepository.getForValidation();\n    const results: Array<T & { pluginMethod: PluginMethodSearchResponse }> = [];\n\n    for (const step of steps) {\n      const pluginMethod = resolveMethod(methods, step.method);\n      if (!pluginMethod) {\n        throw new BadRequestException(`Unknown method ${step.method}`);\n      }\n\n      if (!isMethodCompatible(pluginMethod, trigger)) {\n        throw new BadRequestException(`Method \"${step.method}\" is incompatible with workflow trigger: \"${trigger}\"`);\n      }\n\n      results.push({ ...step, pluginMethod });\n    }\n\n    // TODO make sure all steps can use a common WorkflowType\n\n    return results;\n  }\n\n  private findOrFail(id: string) {\n    return findOrFail(() => this.workflowRepository.get(id), 'Workflow');\n  }\n}","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/workflow.service.ts#L94-L130","documentation":"resolveAndValidateSteps looks up each requested step's method in the plugin repository's available methods (resolveMethod). When no plugin method matches the given step.method name, the step cannot be resolved and a 400 Bad Request 'Unknown method <name>' is thrown.","triggerScenarios":"Creating/updating a workflow (via the steps endpoint) where any step references a method identifier that is not in pluginRepository.getForValidation() — typo'd method names, methods of uninstalled/disabled plugins, or deprecated method ids.","commonSituations":"Client cache listing stale plugin methods after a plugin was updated or removed; hand-written automation scripts using guessed method names; case-sensitivity mistakes in method identifiers; workflows copied between servers with different plugins installed.","solutions":["Fetch the current list of available plugin methods (validation endpoint) and use an exact, existing method id.","Check for typos and case mismatches in step.method.","Install/enable the plugin that provides the referenced method, or remove the step.","Refresh the client so its method list matches the server's installed plugins."],"exampleFix":"// before\n{ \"steps\": [{ \"method\": \"uploadAsset\" }] }\n// after\n// use a method id returned by the plugin methods endpoint\n{ \"steps\": [{ \"method\": \"asset.upload\" }] }","handlingStrategy":"validation","validationCode":"const methods = await api.getPluginMethods();\nconst known = new Set(methods.map((m) => m.id));\nfor (const step of steps) {\n  if (!known.has(step.method)) {\n    throw new Error(`Unknown method ${step.method}`);\n  }\n}","typeGuard":"const isKnownMethod = (m: string, known: Set<string>): m is PluginMethodId => known.has(m);","tryCatchPattern":"try {\n  await api.createWorkflow({ trigger, steps });\n} catch (e) {\n  if (e instanceof BadRequestException && e.message.startsWith('Unknown method')) {\n    // refresh method list and correct the step\n  }\n}","preventionTips":["Always derive step methods from the live plugin-methods endpoint, not hardcoded lists.","Refresh client caches after plugin install/update/removal.","Match method ids exactly — mind case and separators.","Validate workflows before saving so bad methods are caught early."],"tags":["workflow","plugin","unknown-method","validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}