slimtoolkit/slim · error

no project info

Error message

no project info

What it means

NewConfigInfo loads a compose project via compose-go's loader.Load(projectConfig, ...). If loading succeeds but returns a nil project (no project information), the function returns 'no project info'. This indicates the compose configuration could not yield a usable project object despite no hard load error.

Source

Thrown at pkg/app/master/compose/execution.go:276

			projectConfig.Environment = map[string]string{}
		}

		//host env vars override explicit vars
		for _, evar := range os.Environ() {
			parts := strings.SplitN(evar, "=", 2)
			if len(parts) == 2 {
				projectConfig.Environment[parts[0]] = parts[1]
			}
		}
	}

	project, err := loader.Load(projectConfig, withProjectName(projectName))
	if err != nil {
		return nil, err
	}

	if project == nil {
		return nil, fmt.Errorf("no project info")
	}

	cv.Project = project

	return cv, nil
}

func NewExecution(
	xc *app.ExecutionContext,
	logger *log.Entry,
	apiClient *dockerapi.Client,
	composeFiles []string,
	selectors *ServiceSelectors,
	projectName string,
	workingDir string,
	envVars []string,
	environmentNoHost bool,
	containerProbeComposeSvc string,

View on GitHub (pinned to 81940d17fa)

Solutions

  1. Verify the compose file path passed into the config actually exists and is non-empty and defines at least one service
  2. Log/inspect the projectConfig passed to NewConfigInfo before calling it; ensure the loader config (working dir, config files) is populated
  3. Update the compose-go loader library — older versions could return (nil, nil) on edge-case configs; a newer loader returns a proper error instead
  4. Add an explicit nil check upstream so the caller surfaces which input produced the empty project

Example fix

// before
loaderConfig := types.ConfigDetails{} // empty
exe, err := compose.NewExecution(ctx, cli, name, workdir, loaderConfig, ...)
// after
loaderConfig := types.ConfigDetails{
    WorkingDir: workdir,
    ConfigFiles: []string{filepath.Join(workdir, "docker-compose.yml")},
}
exe, err := compose.NewExecution(ctx, cli, name, workdir, loaderConfig, ...)
Defensive patterns

Strategy: validation

Validate before calling

func hasProjectInfo(cfg types.ConfigDetails) error {
    if len(cfg.ConfigFiles) == 0 {
        return fmt.Errorf("no compose config files provided")
    }
    for _, f := range cfg.ConfigFiles {
        fi, err := os.Stat(f)
        if err != nil || fi.IsDir() {
            return fmt.Errorf("compose config %q missing or not a file", f)
        }
        data, _ := os.ReadFile(f)
        if len(strings.TrimSpace(string(data))) == 0 {
            return fmt.Errorf("compose config %q is empty", f)
        }
    }
    return nil
}

Try / catch

cv, err := compose.NewConfigInfo(ctx, cli, name, workdir, cfgDetails, opts)
if err != nil {
    if strings.Contains(err.Error(), "no project info") {
        return fmt.Errorf("compose config at %s produced an empty project: %w", workdir, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling NewExecution/NewConfigInfo with a projectConfig whose contents result in loader.Load returning (nil, nil) — e.g. an empty or effectively empty compose configuration, or a loader path that produced no project definition.

Common situations: Pointing the compose loader at a missing/empty docker-compose.yml, a config file with no services, or passing a serialized config blob that was never populated; also occurs when the project name resolution path returns an empty project.

Related errors


AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31). Data as JSON: /api/errors/b971341407877360. Report an issue: GitHub.