Skip to content

SIGSEGV in fingerprint possibly due to duplicate filenames throughout different dirs and namespaces #2753

@loganfred

Description

@loganfred

Description

My goal is to build a static website using go-task.

I have a hierarchy like this:

.
├── bin
├── output
│   └── public
│       └── html
│           ├── essays
│           └── notes
├── private
│   ├── resume
│   │   └── Taskfile.yml
│   └── Taskfile.yml
├── public
│   ├── essays
│   │   └── Taskfile.yml
│   ├── notes
│   │   └── Taskfile.yml
│   └── Taskfile.yml
└── Taskfile.yml

I want to use fingerprinting to avoid unnecessary work. I don't want conversion to HTML to happen sequentially because it will take forever.

The meat of my solution is as follows:

 compile:
    internal: true
    label: compile-essay-{{.FILE}}
    requires:
      vars: [FILE, OUT_DIR, OUT]
    sources:
      - '{{.FILE}}'
    generates:
      - '{{.OUT}}'
    cmds:
      - pandoc {{.PANDOC_FLAGS}} {{.FILE}} -o {{.OUT}}

  build-all:
    desc: Compile all .md files in parallel with fingerprinting
    silent: true
    vars:
      FILES:
        sh: find {{.SRC_DIR}} -name '*.md' -printf "%f\n"
    deps:
      - for:
          var: FILES
          split: "\n"
          as: FILE
        task: compile
        vars:
          FILE: '{{.FILE}}'
          OUT_DIR: '{{.OUT_DIR}}'
          OUT: '{{.OUT_DIR}}{{base .FILE | trimSuffix ".md"}}.html'

Since I have essays and notes folders, I copied this approach to Taskfile.yml files in both directories so that I can have distinct handling for the different files../bin/task public:essays worked fine, but ./bin/task public:notes would SIGSEGV.

Note that the label is different for essays and notes, the namespace is different, but the task is the same.

The root cause ended up being that both folders had index.md files. Deleting the latter file fixed the issue, changing the label did not. Renaming the file still created the error unless I modified the filetype. These files are in separate namespaces. I still don't really understand-- I would like for the fingerprinting to be based on the label or the namespace or the path. I'm still not quite sure what the workaround is yet.

EDIT: I'm still experiencing the issue so I was wrong about finding a fix. I think the state is getting tangled up somehow. I think using the same VARs in two separate dependencies tasks was causing issues. I switched them to cmds tasks and things are better, but something with the fingerprinting is still failing even if I add a clean step that finds all the .task folders and deletes them.

I'll have to dig into this more to figure out what's going wrong.

I did eventually find the note in the documentation about this but I don't think it should error this way and the logging could be improved.

https://taskfile.dev/docs/guide#by-fingerprinting-locally-generated-files-and-their-sources

Here is what the error looks like. The point that it happens is racey because the file order is different each time and there is no help from echo debugging or --verbose because I think the fingerprinting happens before all that.

(>10  successes)
...
task: [compile-note-200904-0627-change_youtube_speed.md] pandoc --lua-filter=fix-links.lua '200904-0627-change_youtube_speed.md' -o '../../output/public/html/notes/200904-0627-change_youtube_speed.html'

task: [compile-note-240904-1055-mildred.md] pandoc --lua-filter=fix-links.lua '240904-1055-mildred.md' -o '../../output/public/html/notes/240904-1055-mildred.html'

task: [compile-note-20230903-1359_AUTOMATED_way_station_clifford_simak_hugo_award.md] pandoc --lua-filter=fix-links.lua '20230903-1359_AUTOMATED_way_station_clifford_simak_hugo_award.md' -o '../../output/public/html/notes/20230903-1359_AUTOMATED_way_station_clifford_simak_hugo_award.html'

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x62671b]

goroutine 478 [running]:
mvdan.cc/sh/v3/expand.FieldsSeq.func1(0x131e5e200e40)
	mvdan.cc/sh/v3@v3.12.1-0.20260124232039-e74afc18e65b/expand/expand.go:459 +0x9b
mvdan.cc/sh/v3/expand.Fields(0x131e5e0ce140, {0x131e5c282508, 0x1, 0x1})
	mvdan.cc/sh/v3@v3.12.1-0.20260124232039-e74afc18e65b/expand/expand.go:442 +0x125
github.com/go-task/task/v3/internal/execext.ExpandFields({0x131e5e0aa1e0?, 0x39?})
	github.com/go-task/task/v3@v3.49.1/internal/execext/exec.go:139 +0x18e
github.com/go-task/task/v3/internal/fingerprint.glob({0x131e5cf1a980?, 0x131e5d833570?}, {0x131e5c2d9080?, 0x18?})
	github.com/go-task/task/v3@v3.49.1/internal/fingerprint/glob.go:29 +0x37
github.com/go-task/task/v3/internal/fingerprint.Globs({0x131e5cf1a980, 0x39}, {0x131e5c2823c0, 0x1, 0x0?})
	github.com/go-task/task/v3@v3.49.1/internal/fingerprint/glob.go:15 +0xfb
github.com/go-task/task/v3/internal/fingerprint.(*ChecksumChecker).checksum(0x425d85?, 0x18?)
	github.com/go-task/task/v3@v3.49.1/internal/fingerprint/sources_checksum.go:91 +0x45
github.com/go-task/task/v3/internal/fingerprint.(*ChecksumChecker).Value(0x0?, 0x131e5da93080?)
	github.com/go-task/task/v3@v3.49.1/internal/fingerprint/sources_checksum.go:76 +0x13
github.com/go-task/task/v3.(*Executor).compiledTask(0x131e5c638f00, 0x131e5c6056e0, 0x0)
	github.com/go-task/task/v3@v3.49.1/variables.go:193 +0xfd4
github.com/go-task/task/v3.(*Executor).FastCompiledTask(...)
	github.com/go-task/task/v3@v3.49.1/variables.go:30
github.com/go-task/task/v3.(*Executor).RunTask(0x131e5c638f00, {0x209ae80, 0x3385860}, 0x131e5c6056e0)
	github.com/go-task/task/v3@v3.49.1/task.go:142 +0x1a8
github.com/go-task/task/v3.(*Executor).runDeps.func1()
	github.com/go-task/task/v3@v3.49.1/task.go:329 +0x9a
golang.org/x/sync/errgroup.(*Group).Go.func1()
	golang.org/x/sync@v0.19.0/errgroup/errgroup.go:93 +0x50
created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 1
	golang.org/x/sync@v0.19.0/errgroup/errgroup.go:78 +0x95

Version

3.49.1

Operating system

Linux ARCH 6.19.8-arch1-1 #1 SMP PREEMPT_DYNAMIC Sat, 14 Mar 2026 01:07:43 +0000 x86_64 GNU/Linux

Experiments Enabled

No response

Example Taskfile

# yaml-language-server: $schema=https://taskfile.dev/schema.json

# copy this file into two separate directories at the same level, add them as includes, then execute as cmd tasks

version: '3'

vars:
  OUT_DIR: ../../output/public/html/notes/

tasks:
  default:
    vars:
      FILES:
        sh: find . -name '*.md' -printf "%f\n"
    deps:
      - for:
          var: FILES
          split: "\n"
          as: FILE
        task: compile
        vars:
          FILE: '{{.FILE}}'
          OUT_DIR: '{{.OUT_DIR}}'

  compile:
    internal: true
    label: 'compile-{{.FILE}}'
    requires:
      vars: [FILE, OUT_DIR]
    sources:
      - '{{.FILE}}'
    generates:
      - '{{.OUT_DIR}}/{{base .FILE | trimSuffix ".md"}}.html'
    cmds:
      - >
        pandoc --lua-filter=fix-links.lua
        -o '{{.OUT_DIR}}/{{base .FILE | trimSuffix ".md"}}.html'
        '{{.FILE}}'

Metadata

Metadata

Assignees

No one assigned

    Labels

    state: needs triageWaiting to be triaged by a maintainer.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions