{"record":{"id":"400a30c3d5f8bd9c","repo":"angular/angular","slug":"loading-block-can-only-have-one-minimum-paramet","errorCode":null,"errorMessage":"@loading block can only have one \"minimum\" parameter","messagePattern":"@loading block can only have one \"minimum\" parameter","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/compiler/src/render3/r3_deferred_blocks.ts","lineNumber":226,"sourceCode":"\n  for (const param of ast.parameters) {\n    if (AFTER_PARAMETER_PATTERN.test(param.expression)) {\n      if (afterTime != null) {\n        throw new Error(`@loading block can only have one \"after\" parameter`);\n      }\n\n      const parsedTime = parseDeferredTime(\n        param.expression.slice(getTriggerParametersStart(param.expression)),\n      );\n\n      if (parsedTime === null) {\n        throw new Error(`Could not parse time value of parameter \"after\"`);\n      }\n\n      afterTime = parsedTime;\n    } else if (MINIMUM_PARAMETER_PATTERN.test(param.expression)) {\n      if (minimumTime != null) {\n        throw new Error(`@loading block can only have one \"minimum\" parameter`);\n      }\n\n      const parsedTime = parseDeferredTime(\n        param.expression.slice(getTriggerParametersStart(param.expression)),\n      );\n\n      if (parsedTime === null) {\n        throw new Error(`Could not parse time value of parameter \"minimum\"`);\n      }\n\n      minimumTime = parsedTime;\n    } else {\n      throw new Error(`Unrecognized parameter in @loading block: \"${param.expression}\"`);\n    }\n  }\n\n  return new t.DeferredBlockLoading(\n    html.visitAll(visitor, ast.children, ast.children),","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/angular/angular/blob/51cb07e98081ab7e4e84a9e0949266a8e19cca84/packages/compiler/src/render3/r3_deferred_blocks.ts#L208-L244","documentation":"An @loading sub-block of @defer declares the `minimum` parameter more than once. `minimum` controls how long the loading indicator stays visible once shown; the compiler keeps it in a single `minimumTime` field, so when the parameter loop encounters a second /^minimum\\s/ match while `minimumTime != null`, it throws.","triggerScenarios":"`@loading (minimum 1s; minimum 2s) {...}` — two parameters matching /^minimum\\s/ in the same @loading block (parameters separated by `;`).","commonSituations":"Duplicating a parameter while copy-pasting timing configuration, or merging templates after a refactor. Developers sometimes add a second `minimum` intending to change the value instead of editing the first one.","solutions":["Delete the duplicate and keep one `minimum` parameter","If you intended two timings, use the valid combination `after <time>; minimum <time>`"],"exampleFix":"// before\n@loading (minimum 1s; minimum 2s) {\n  Loading...\n}\n// after\n@loading (minimum 2s) {\n  Loading...\n}","handlingStrategy":"validation","validationCode":"function validateLoadingParams(params: string[]): string | null {\n  const minCount = params.filter((p) => /^minimum\\s/.test(p)).length;\n  return minCount > 1 ? 'Duplicate \"minimum\" parameter in @loading' : null;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["@loading takes at most one minimum and one after parameter.","Lint duplicated defer parameters in code review when templates are merged."],"tags":["angular","defer","loading","template-syntax","aot-compiler"],"backgroundTag":"angular-defer-block-syntax","analyzedSha":"51cb07e98081ab7e4e84a9e0949266a8e19cca84","analyzedAt":"2026-08-22T07:04:54.531Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}