Skip to content

One vat's stream breaking during startup stops the whole kernel #1069

Description

@sirtimid

Found reviewing #1023 (sirtimid/vat-lifecycle-consistency-v2).

What

runVat's new if (fatalError) throw fatalError; makes initializeAllVats' Promise.all reject, which rejects Kernel.#init — so the run loop never starts.

A single vat whose worker dies during initVat (a blocked iframe, a missing worker file, a bundle fetch dying mid-handshake) therefore takes down every other vat with it.

The rethrow is right for launchVat, whose caller needs the failure. It is wrong for startup, where #retireVat has already recorded that vat as dead and durably committed it, so the kernel could simply come up without it.

Suggested fix

Catch per vat in initializeAllVats, and only swallow once the vat is provably recorded dead — a platformServices.launch rejection leaves it store-active with no handle, which the first delivery to it turns into a dead run loop via #resolveEndpoint:

starts.push(
  this.runVat(vatID, vatConfig).catch((error) => {
    this.#logger.error(`Vat ${vatID} failed to start:`, error);
    if (this.#kernelStore.isVatActive(vatID)) {
      this.#retireVat(vatID, asError(error));
    }
  }),
);

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions