golang-migrate/migrate · error

time format may not be empty

Error message

time format may not be empty

What it means

errInvalidTimeFormat ('time format may not be empty') is returned by timeVersion when `migrate create` runs without -seq but with an empty -format string. Time-based versioning derives the version from startTime using the given format; an empty format cannot produce a version, so the command fails early.

Source

Thrown at internal/cli/commands.go:20

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/golang-migrate/migrate/v4"
	_ "github.com/golang-migrate/migrate/v4/database/stub" // TODO remove again
	_ "github.com/golang-migrate/migrate/v4/source/file"
)

var (
	errInvalidSequenceWidth     = errors.New("digits must be positive")
	errIncompatibleSeqAndFormat = errors.New("the seq and format options are mutually exclusive")
	errInvalidTimeFormat        = errors.New("time format may not be empty")
)

func nextSeqVersion(matches []string, seqDigits int) (string, error) {
	if seqDigits <= 0 {
		return "", errInvalidSequenceWidth
	}

	nextSeq := uint64(1)

	if len(matches) > 0 {
		filename := matches[len(matches)-1]
		matchSeqStr := filepath.Base(filename)
		idx := strings.Index(matchSeqStr, "_")

		if idx < 1 { // Using 1 instead of 0 since there should be at least 1 digit
			return "", fmt.Errorf("malformed migration filename: %s", filename)
		}

View on GitHub (pinned to 01a9643f14)

Solutions

  1. Pass a valid -format, e.g. -format unix, -format unixNano, or a Go time layout like 20060102150405.
  2. Drop the empty -format flag entirely to use the default time format.
  3. Fix the wrapper/CI variable so a non-empty format is supplied.
  4. Validate the format value in your script before invoking migrate create.

Example fix

// before
migrate create -format "" -ext sql -dir migrations add_index
// after
migrate create -format unix -ext sql -dir migrations add_index
Defensive patterns

Strategy: validation

Validate before calling

if [ -n "${FORMAT+x}" ] && [ -z "$FORMAT" ]; then
	echo "FORMAT must be non-empty (unix, unixNano, or a Go time layout)"; exit 1
fi

Prevention

When it happens

Trigger: Running `migrate create -format "" ...` or a wrapper that always passes a -format value which is unset/empty; timeVersion's switch receives format "" and sets err = errInvalidTimeFormat.

Common situations: CI templates with an interpolatable format variable that resolves to empty; quoting mistakes that yield a zero-length argument; users omitting -format while their wrapper still forwards the flag with an empty value.

Understand the failure class

Background: "must be a positive integer", "cannot be empty", "invalid argument": how invalid-argument errors work across open-source libraries — this error's family across 33 libraries.

Related errors


AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02). Data as JSON: /api/errors/d48d8443984bea1a. Report an issue: GitHub.