{"record":{"id":"c5597635a3b7883e","repo":"wavetermdev/waveterm","slug":"static-files-not-available-before-app-initializati","errorCode":null,"errorMessage":"static files not available before app initialization; use AppInit to access files during initialization","messagePattern":"static files not available before app initialization; use AppInit to access files during initialization","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tsunami/app/defaultclient.go","lineNumber":219,"sourceCode":"\t\tsecretDesc = meta.Desc\n\t\tsecretOptional = meta.Optional\n\t}\n\tclient.DeclareSecret(secretName, secretDesc, secretOptional)\n\treturn os.Getenv(secretName)\n}\n\nfunc PrintAppManifest() {\n\tclient := engine.GetDefaultClient()\n\tclient.PrintAppManifest()\n}\n\n// ReadStaticFile reads a file from the embedded static filesystem.\n// The path MUST start with \"static/\" (e.g., \"static/config.json\").\n// Returns the file contents or an error if the file doesn't exist or can't be read.\nfunc ReadStaticFile(path string) ([]byte, error) {\n\tclient := engine.GetDefaultClient()\n\tif client.StaticFS == nil {\n\t\treturn nil, errors.New(\"static files not available before app initialization; use AppInit to access files during initialization\")\n\t}\n\tif !strings.HasPrefix(path, \"static/\") {\n\t\treturn nil, fmt.Errorf(\"ReadStaticFile path must start with 'static/': %w\", fs.ErrNotExist)\n\t}\n\t// Strip \"static/\" prefix since the FS is already sub'd to the static directory\n\trelativePath := strings.TrimPrefix(path, \"static/\")\n\treturn fs.ReadFile(client.StaticFS, relativePath)\n}\n\n// OpenStaticFile opens a file from the embedded static filesystem.\n// The path MUST start with \"static/\" (e.g., \"static/config.json\").\n// Returns an fs.File or an error if the file doesn't exist or can't be opened.\nfunc OpenStaticFile(path string) (fs.File, error) {\n\tclient := engine.GetDefaultClient()\n\tif client.StaticFS == nil {\n\t\treturn nil, errors.New(\"static files not available before app initialization; use AppInit to access files during initialization\")\n\t}\n\tif !strings.HasPrefix(path, \"static/\") {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/tsunami/app/defaultclient.go#L201-L237","documentation":"ReadStaticFile reads from the app's embedded static filesystem, which is attached to the default client only after app initialization completes. Calling it earlier (StaticFS is nil) returns this error directing you to AppInit, where static files are accessible during initialization.","triggerScenarios":"Calling tsunami/app.ReadStaticFile(path) before the app's initialization finished — engine.GetDefaultClient() returns a client whose StaticFS field is still nil (outside or early in AppInit).","commonSituations":"Reading static config assets at package init time; accessing embedded files in constructors that run before AppInit; tests that call ReadStaticFile without booting the app.","solutions":["Move the ReadStaticFile call after app initialization completes (post-AppInit).","If you need files during initialization, read them inside the AppInit callback where StaticFS is available.","Ensure the app's startup path actually populates StaticFS before dependent code runs.","For pure-asset needs, use embed.FS directly in your package instead of the app client.","Add a startup ordering guard/assert that StaticFS is set before consumers run."],"exampleFix":"// before\nfunc init() {\n    data, _ := app.ReadStaticFile(\"static/config.json\") // too early\n}\n// after\nfunc OnInit(ctx context.Context) error {\n    data, err := app.ReadStaticFile(\"static/config.json\") // inside AppInit\n    ...\n}","handlingStrategy":"validation","validationCode":"if client.StaticFS == nil {\n    return nil, fmt.Errorf(\"static FS not ready; call from AppInit or later\")\n}","typeGuard":null,"tryCatchPattern":"data, err := app.ReadStaticFile(\"static/config.json\")\nif err != nil {\n    return fmt.Errorf(\"read static config: %w\", err)\n}","preventionTips":["Call static-file helpers only after AppInit completes.","Use the AppInit callback for init-time asset access.","Never read static assets in package init()/constructors.","Assert StaticFS != nil in startup ordering checks."],"tags":["go","static-files","initialization"],"backgroundTag":"static-files-not-initialized","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}