{"record":{"id":"46a15adf81f3bc6a","repo":"hashicorp/terraform","slug":"global-logger-is-not-an-interceptlogger","errorCode":null,"errorMessage":"global logger is not an InterceptLogger","messagePattern":"global logger is not an InterceptLogger","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/logging/logging.go","lineNumber":69,"sourceCode":"\n\tGraphTrace = os.Getenv(envGraphTrace) != \"\"\n)\n\nfunc init() {\n\tlogger = newHCLogger(\"\")\n\tlogWriter = logger.StandardWriter(&hclog.StandardLoggerOptions{InferLevels: true})\n\n\t// set up the default std library logger to use our output\n\tlog.SetFlags(0)\n\tlog.SetPrefix(\"\")\n\tlog.SetOutput(logWriter)\n}\n\n// SetupTempLog adds a new log sink which writes all logs to the given file.\nfunc RegisterSink(f *os.File) {\n\tl, ok := logger.(hclog.InterceptLogger)\n\tif !ok {\n\t\tpanic(\"global logger is not an InterceptLogger\")\n\t}\n\n\tif f == nil {\n\t\treturn\n\t}\n\n\tl.RegisterSink(hclog.NewSinkAdapter(&hclog.LoggerOptions{\n\t\tLevel:  hclog.Trace,\n\t\tOutput: f,\n\t}))\n}\n\n// LogOutput return the default global log io.Writer\nfunc LogOutput() io.Writer {\n\treturn logWriter\n}\n\n// HCLogger returns the default global hclog logger","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/logging/logging.go#L51-L87","documentation":"Panics in RegisterSink (logging.go:69). It type-asserts the package-global logger to hclog.InterceptLogger to attach a file sink; if the global logger has been replaced with a plain hclog.Logger the assertion fails and panics.","triggerScenarios":"Code overwrites the package-global logger (e.g. via reassigning logging's logger or embedding Terraform as a library) with a non-Intercept hclog.Logger, then RegisterSink runs (when TF_LOG_PATH / temp logging is configured).","commonSituations":"Test harnesses or forks that swap in a custom logger; embedding Terraform as a library and replacing the logger with hclog.New instead of hclog.NewInterceptLogger.","solutions":["Do not replace the global logger with a non-Intercept logger.","If you must replace it, wrap with hclog.NewInterceptLogger so the assertion holds.","Leave logger initialization to logging.newHCLogger which already produces an InterceptLogger."],"exampleFix":"// before\nlogger = hclog.New(&hclog.LoggerOptions{Name: \"x\"})\n// after\nlogger = hclog.NewInterceptLogger(&hclog.LoggerOptions{Name: \"x\"})","handlingStrategy":"type-guard","validationCode":"func canRegisterSink(l hclog.Logger) error {\n    if _, ok := l.(hclog.InterceptLogger); !ok {\n        return fmt.Errorf(\"global logger must be InterceptLogger\")\n    }\n    return nil\n}","typeGuard":"func isInterceptLogger(l hclog.Logger) bool {\n    _, ok := l.(hclog.InterceptLogger)\n    return ok\n}","tryCatchPattern":null,"preventionTips":["Do not replace the global logger with a non-Intercept logger.","If replacing, use hclog.NewInterceptLogger.","Leave logger init to logging.newHCLogger."],"tags":["terraform","logging","hclog","panic"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}