{"record":{"id":"6218a2def78de2b0","repo":"microsoft/aspire","slug":"hmp1-protocol-error-invalid-frame-length-length-type-type","errorCode":null,"errorMessage":"HMP1 protocol error: invalid frame length ${length} (type=${type}).","messagePattern":"HMP1 protocol error: invalid frame length (.+?) \\(type=(.+?)\\)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Aspire.Dashboard/wwwroot/js/hmp1-client.js","lineNumber":80,"sourceCode":"      }\n      yield frame;\n    }\n  }\n\n  _tryReadOne() {\n    if (this._totalLength < HEADER_SIZE) {\n      return null;\n    }\n    const header = this._peek(HEADER_SIZE);\n    const dv = new DataView(header.buffer, header.byteOffset, HEADER_SIZE);\n    const type = dv.getUint8(0);\n    const length = dv.getInt32(1, true);\n    // Reject negative lengths (would desync the buffer because\n    // `total < HEADER_SIZE`) and absurdly large lengths (would attempt to\n    // allocate a multi-GiB Uint8Array which either throws inside the\n    // `message` handler - silently wedging the client - or OOMs the tab).\n    if (length < 0 || length > MAX_FRAME_PAYLOAD) {\n      throw new Error(`HMP1 protocol error: invalid frame length ${length} (type=${type}).`);\n    }\n    const total = HEADER_SIZE + length;\n    if (this._totalLength < total) {\n      return null;\n    }\n    const payload = this._take(total).slice(HEADER_SIZE);\n    return { type, payload };\n  }\n\n  _peek(n) {\n    return this._concat(n, /* consume */ false);\n  }\n\n  _take(n) {\n    return this._concat(n, /* consume */ true);\n  }\n\n  _concat(n, consume) {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Dashboard/wwwroot/js/hmp1-client.js#L62-L98","documentation":"Aspire's hosting pipeline exposes a built-in Diagnostics step that dumps the dependency graph of pipeline steps for troubleshooting. The dump operates on the step data resolved (flattened/validated) during the last ExecuteAsync call, cached in _lastResolvedSteps. If no execution has happened yet, that cache is null and the library throws this InvalidOperationException instead of producing misleading empty output.","triggerScenarios":"Running the pipeline's diagnostics step (WellKnownPipelineSteps.Diagnostics) before ever calling DistributedApplicationPipeline.ExecuteAsync, or after recreating the pipeline instance. The diagnostics step is invoked in a context (e.g. debugging hook, --diagnostics flag path) that does not itself execute the pipeline first.","commonSituations":"Developers wiring up pipeline diagnostics tooling or tests that invoke the diagnostics step directly; running diagnostics in a separate process or pipeline instance from the one that executed the model; calling diagnostic dumps from app-model inspection code before publish/deploy has run.","solutions":["Execute the pipeline first by calling await pipeline.ExecuteAsync(model) before running the diagnostics step, so the resolved step data is cached.","Verify the diagnostics call targets the same DistributedApplicationPipeline instance that executed; create a new pipeline instance loses _lastResolvedSteps.","In tests or tooling, run ExecuteAsync inside try/catch or with a throwaway model to populate diagnostics data, then dump the graph.","If diagnostics must run standalone, inspect the pipeline via public step enumeration APIs instead of the Diagnostics step."],"exampleFix":"// before\nawait diagnosticsStep.ExecuteAsync(context); // throws: no execution yet\n// after\nawait pipeline.ExecuteAsync(appModel);       // populates resolved step data\nawait diagnosticsStep.ExecuteAsync(context); // now dumps dependency graph","handlingStrategy":"validation","validationCode":"// C#: ensure the pipeline executed before diagnostics\nif (pipeline.GetType().GetProperty(\"HasSteps\") is null)\n    throw new InvalidOperationException(\"Pipeline not initialized\");\nawait pipeline.ExecuteAsync(model); // must run before diagnostics step","typeGuard":"bool IsPipelineExecuted(CompilationResult? lastResult) => lastResult is not null;","tryCatchPattern":"try\n{\n    await pipeline.ExecuteAsync(model);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"No resolved pipeline data available\"))\n{\n    logger.LogWarning(ex, \"Diagnostics ran before pipeline execution; run ExecuteAsync first.\");\n}","preventionTips":["Always pair diagnostics collection with a prior ExecuteAsync call on the same pipeline instance.","Do not construct a fresh pipeline for diagnostics; reuse the executed instance.","In CI diagnostics tooling, assert execution completed before dumping the graph."],"tags":["pipeline","diagnostics","aspire","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}