{"record":{"id":"99ebe51a1eeefca2","repo":"AlistGo/alist","slug":"lark-tenant-access-token-is-empty","errorCode":null,"errorMessage":"lark tenant access token is empty","messagePattern":"lark tenant access token is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/lark/driver.go","lineNumber":453,"sourceCode":"\t\t\treturn \"\", err\n\t\t}\n\t}\n\tif accessToken != \"\" {\n\t\treturn accessToken, nil\n\t}\n\n\tresp, err := c.client.GetTenantAccessTokenBySelfBuiltApp(ctx, &larkcore.SelfBuiltTenantAccessTokenReq{\n\t\tAppID:     c.AppId,\n\t\tAppSecret: c.AppSecret,\n\t})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif !resp.Success() {\n\t\treturn \"\", errors.New(resp.Error())\n\t}\n\tif resp.TenantAccessToken == \"\" {\n\t\treturn \"\", errors.New(\"lark tenant access token is empty\")\n\t}\n\treturn resp.TenantAccessToken, nil\n}\n\nfunc (c *Lark) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {\n\ttoken, ok := c.getObjToken(ctx, parentDir.GetPath())\n\tif !ok {\n\t\treturn nil, errs.ObjectNotFound\n\t}\n\n\tbody, err := larkdrive.NewCreateFolderFilePathReqBodyBuilder().FolderToken(token).Name(dirName).Build()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := doDrive(ctx, c, func(opts ...larkcore.RequestOptionFunc) (*larkdrive.CreateFolderFileResp, error) {\n\t\treturn c.client.Drive.File.CreateFolder(ctx,\n\t\t\tlarkdrive.NewCreateFolderFileReqBuilder().Body(body).Build(), opts...)","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/lark/driver.go#L435-L471","documentation":"getTenantAccessTokenBySelfBuiltApp succeeded (resp.Success() true) but TenantAccessToken came back empty. The tenant token authenticates app-level Drive calls (folder creation, listing); an empty one would make every subsequent API call anonymous. Guard fails fast right after the SDK success check.","triggerScenarios":"Self-built-app token endpoint returns success envelope with blank tenant_access_token — wrong AppId/AppSecret combination accepted syntactically, app not published/enabled in the Feishu console, or response shape drift in the lark SDK.","commonSituations":"Copy-pasted app credentials with trailing whitespace or from a different app; app still in draft/unenabled state; missing required scopes so the endpoint returns a success body without a token.","solutions":["Verify AppId/AppSecret in the storage config exactly match the self-built app's credentials in the Feishu open platform console","Ensure the app is enabled/published and has drive scopes granted","Test credentials with a direct curl to the tenant_access_token endpoint to see the raw response","Update alist/lark SDK if the response schema changed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if strings.TrimSpace(c.AppId) == \"\" || strings.TrimSpace(c.AppSecret) == \"\" {\n\treturn errors.New(\"lark app_id and app_secret are required\")\n}","typeGuard":null,"tryCatchPattern":"tok, err := c.getTenantAccessToken(ctx)\nif err != nil && strings.Contains(err.Error(), \"tenant access token is empty\") {\n\t// credentials accepted syntactically but app not usable: verify console state\n\treturn \"\", fmt.Errorf(\"lark app returned no tenant token; check app status/scopes: %w\", err)\n}","preventionTips":["Validate credentials at storage-add time with a tenant-token call before enabling","Keep the app enabled and scopes granted in the Feishu console; re-check after app reviews"],"tags":["lark","feishu","authentication","app-credentials","driver"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}