apache/beam · critical

panic(msg)

Error message

panic(msg)

What it means

log.Fatal in the Beam Go log package writes the fmt.Sprint-formatted arguments at fatal severity to the global logger, then panics with the message. It is the logging library's terminal-failure helper: after logging, execution cannot continue, so it deliberately raises a panic that typically crashes the pipeline.

Solutions

  1. This is intentional behavior; prevent hitting it by validating config and dependencies before calling Fatal paths.
  2. If you need controlled failure instead of a panic, log at fatal severity and return an error rather than calling Fatal.
  3. In tests, use recover() in TestMain if you must assert that Fatal was invoked.
Defensive patterns

Strategy: try-catch

Try / catch

defer func() {
    if r := recover(); r != nil {
        fmt.Fprintf(os.Stderr, "fatal: %v\n", r)
        os.Exit(1)
    }
}()

Prevention

When it happens

Trigger: Any application code calling log.Fatal(ctx, ...) for unrecoverable conditions — e.g. failed config loads, unreachable dependencies — in main functions, test mains, or loader helpers.

Common situations: Aborting on missing configuration or failed datastore/entity loads at startup; unrecoverable initialization errors in CLI tools and test setups.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/b22b7dc825baf68b. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/log/log.go:165

// Errorf writes the fmt.Sprintf-formatted arguments to the global logger with
// error severity.
func Errorf(ctx context.Context, format string, v ...any) {
	Output(ctx, SevError, 1, fmt.Sprintf(format, v...))
}

// Errorln writes the fmt.Sprintln-formatted arguments to the global logger with
// error severity.
func Errorln(ctx context.Context, v ...any) {
	Output(ctx, SevError, 1, fmt.Sprintln(v...))
}

// Fatal writes the fmt.Sprint-formatted arguments to the global logger with
// fatal severity. It then panics.
func Fatal(ctx context.Context, v ...any) {
	msg := fmt.Sprint(v...)
	Output(ctx, SevFatal, 1, msg)
	panic(msg)
}

// Fatalf writes the fmt.Sprintf-formatted arguments to the global logger with
// fatal severity. It then panics.
func Fatalf(ctx context.Context, format string, v ...any) {
	msg := fmt.Sprintf(format, v...)
	Output(ctx, SevFatal, 1, msg)
	panic(msg)
}

// Fatalln writes the fmt.Sprintln-formatted arguments to the global logger with
// fatal severity. It then panics.
func Fatalln(ctx context.Context, v ...any) {
	msg := fmt.Sprintln(v...)
	Output(ctx, SevFatal, 1, msg)
	panic(msg)
}

View on GitHub (pinned to 12126d8942)