Skip to content

Support for no current library - #3396

Closed
buzzia2001 wants to merge 7 commits into
masterfrom
fix/crtdftLibProfile
Closed

Support for no current library#3396
buzzia2001 wants to merge 7 commits into
masterfrom
fix/crtdftLibProfile

Conversation

@buzzia2001

@buzzia2001 buzzia2001 commented Aug 1, 2026

Copy link
Copy Markdown
Member

Changes

This PR enables the user to remove the current library list (the equivalent of using CHGLIBL CURLIB(*CRTDFT)).
image

It adds a new "Remove Current Library" action in the library list view, on the Current library node.
image
image

Using a blank current library or *CRTDFT in a profile will result in having no current library as well.
image

How to test this PR

  1. Click on the "Remove current library" action
  2. Browse source files and open members
  3. Run an action
  4. Switch between profiles (one with and one without a current library)

Checklist

  • have tested my change

Closes #3383

@buzzia2001
buzzia2001 requested a review from sebjulliand August 1, 2026 10:31
@buzzia2001 buzzia2001 self-assigned this Aug 1, 2026
@buzzia2001 buzzia2001 added the bug A confirmed issue when something isn't working as intended label Aug 1, 2026
@buzzia2001
buzzia2001 had a problem deploying to testing_environment August 1, 2026 10:31 — with GitHub Actions Failure
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

👋 A new build is available for this PR based on 7a166e0.

@buzzia2001
buzzia2001 requested review from a team and SanjulaGanepola August 1, 2026 10:32
@buzzia2001
buzzia2001 had a problem deploying to testing_environment August 1, 2026 11:44 — with GitHub Actions Failure
@bobcozzi

bobcozzi commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Thanks for tackling this — the overall approach is right. A few things to address before merging:

Blocker — [IBMi.ts] temp library fallback could be set to *CRTDFT

When a user's profile has CURLIB=*CRTDFT, QSYS2.QSQLIBL() returns no CURRENT row, so the currentLibrary local variable stays as *CRTDFT. That value gets passed as fallbackTempLib into checkOrCreateTempLibrary.

In checkOrCreateTempLibrary (~line 1106 in IBMi.ts), if the configured temp library cannot be created:

else if (fallbackTempLib && !fallbackTempLib.startsWith(`Q`)) {
    this.config.tempLibrary = fallbackTempLib;
}

*CRTDFT is truthy and doesn't start with Q, so it passes the guard and breaks the temp library.

The fix belongs in the connect() function (~line 748 in IBMi.ts), where currentLibrary is declared and used in two places that need different fallback values:

let currentLibrary: string | undefined;  // undefined = no CURRENT row in QSQLIBL

// config gets the honest value for display
if (this.config.currentLibrary.length === 0) {
    this.config.currentLibrary = currentLibrary ?? `*CRTDFT`;
}

// fallback temp lib must always be a real library
const tempLibrarySet = await this.checkOrCreateTempLibrary(currentLibrary ?? `QGPL`, callbacks.message);

Minor — connectionProfileEditor.ts: case-sensitive check

data.currentLibrary === '*CRTDFT' will fail if the user types *crtdft in lowercase. Consider data.currentLibrary.toUpperCase() === '*CRTDFT'.

Minor — LibraryListView.ts: library: 'QSYS' on the synthetic node

*CRTDFT is not in QSYS. If any context menu action uses object.library, it will land on QSYS unexpectedly. Using library: '*CRTDFT' or an empty string would be more accurate.

@bobcozzi

bobcozzi commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Thanks for the effort on this PR — the issue it addresses (#3383) is real, and I understand why it's annoying to see red highlighting when *CRTDFT is set as the current library. That said, after reviewing the changes I want to share some context on what *CRTDFT actually means on IBM i and why full support for it is more involved than it might appear.

What *CRTDFT means on IBM i

*CRTDFT is a user profile attribute — specifically the CURLIB parameter of CRTUSRPRF/CHGUSRPRF. It means "this user has no current library assigned." Originally it was likely "Use a default library for creation commands." It is not an actually library name. Creation commands will use QGPL when *CURLIB is specified and the User Profile has CURLIB(*CRTDFT) specified. When a job signs on for a user with CURLIB(*CRTDFT), QSYS2.QSQLIBL() and the DSPLIBL command return no library with TYPE = 'CURRENT' unless the user used CHGCURLIB or CHGLIBL w/CURLIB parameter. The current library slot in the library list is simply absent. On IBM i, *CRTDFT is only valid as a parameter value in contexts that explicitly document it, such as CHGUSRPRF CURLIB(*CRTDFT) that I mentioned. It is not valid as a qualified object library name — *CRTDFT/MYPGM in any context on the system.

Who uses it

This is rarely, if ever, set for developers. Most developers on IBM i have a dedicated current library (often it is their own development library) explicitly assigned in their user profile. However, it is fairly common for end-users and batch job profiles on production systems where there is intentionally no designated current library, relying entirely on the library list for object resolution. So while it may seem like an edge case for the developer community that uses this extension, it matters to shops where developers connect as themselves but also manage or impersonate other end-user profiles (e.g., testing/debugging).

What the PR does well

The changes to IBMiContent.getLibraryList() (the empty array guard) and LibraryListView (synthesizing the *CRTDFT node at the top of the list) are correct and solve the display issue cleanly. The connectionProfileEditor change allowing *CRTDFT to be saved without hitting checkObject is also the right direction.

What concerns me

The change to the default sentinel in IBMi.connect() from QGPL to *CRTDFT introduces a subtle but real bug. That local variable is passed as fallbackTempLib to checkOrCreateTempLibrary(). Inside that function, if the configured temp library cannot be created, there is a fallback path of:

// src/api/IBMi.ts ~line 1106 — checkOrCreateTempLibrary()
else if (fallbackTempLib && !fallbackTempLib.startsWith(`Q`)) {
    this.config.tempLibrary = fallbackTempLib;
}

IMPORTANT!
The !startsWith('Q') guard was written to prevent IBM i system libraries (QGPL, QTEMP, etc.) from being used as a temp library. *CRTDFT does not start with Q, so it passes the guard, and config.tempLibrary gets set to *CRTDFT — which is not a real library. Anything that subsequently tries to use the temp library would fail. The fix is straightforward: use undefined as the initial value and apply different fallbacks at each location — *CRTDFT for config.currentLibrary (honest display) and QGPL for checkOrCreateTempLibrary (safe real library).

Beyond that, a broader pass is needed. Variable &CURLIB in variables.ts expands directly to config.currentLibrary. This means every compile command template in LocalLanguageActions.ts — CRTBNDRPG, CRTSQLCBLI, CRTBNDCL, and 20+ others — would generate PGM(*CRTDFT/OBJECTNAME) which is invalid IBM i object qualification syntax. SBMJOB CURLIB(*CRTDFT) in debug/index.ts is also likely invalid for that parameter. These are separate issues that need their own fixes, but they are directly enabled by this PR storing *CRTDFT in config.currentLibrary.

My recommendation

The intent of this PR is correct and worth pursuing. But I would suggest not merging it until at minimum the checkOrCreateTempLibrary fallback bug is addressed, and until the team has discussed how &CURLIB expansion should behave when the value is *CRTDFT.

The relevant expansion in src/api/variables.ts:

// current code
if (!this.has(`&CURLIB`)) {
  this.set(`&CURLIB`, config.currentLibrary);         // → '*CRTDFT' — invalid as LIB/OBJ qualifier
}
if (!this.has(`\\*CURLIB`)) {
  this.set(`\\*CURLIB`, config.currentLibrary);       // → '*CRTDFT' — same problem
}

The fix — translate *CRTDFT to *CURLIB before expanding:

// proposed fix
const curlib = config.currentLibrary === `*CRTDFT` ? `*CURLIB` : config.currentLibrary;
if (!this.has(`&CURLIB`)) {
  this.set(`&CURLIB`, curlib);                        // → '*CURLIB' — valid in PGM(*CURLIB/NAME)
}
if (!this.has(`\\*CURLIB`)) {
  this.set(`\\*CURLIB`, curlib);
}

This one change in variables.ts would protect all 20+ compile command templates in LocalLanguageActions.ts at once, since they all go through this expansion path.

Happy to help work through any of this further. The issue and the fix direction are solid — it just needs a bit more depth before it's safe to ship.

@buzzia2001
buzzia2001 marked this pull request as draft August 1, 2026 16:34
@SanjulaGanepola

Copy link
Copy Markdown
Member

@buzzia2001 Given that we closed the issue as not planned, should we close this PR?

@buzzia2001 buzzia2001 closed this Aug 13, 2026
Signed-off-by: Seb Julliand <sebjulliand@gmail.com>
Signed-off-by: Seb Julliand <sebjulliand@gmail.com>
Signed-off-by: Seb Julliand <sebjulliand@gmail.com>
@sebjulliand sebjulliand reopened this Aug 26, 2026
@sebjulliand
sebjulliand marked this pull request as ready for review August 26, 2026 20:56
@sebjulliand

Copy link
Copy Markdown
Member

@SanjulaGanepola @buzzia2001 @bobcozzi we're back in business on *CRTDFT.

I completed the PR and hopefully covered all the edge cases. It was mostly about using *CURLIB here and there when the current library is set to *CRTDFT.

If you can review it and test it a bit, that would be great. Thanks!

@buzzia2001

Copy link
Copy Markdown
Member Author
image

@sebjulliand

Copy link
Copy Markdown
Member

@buzzia2001 right! Let's kill it this time.

@sebjulliand sebjulliand changed the title Support for *CRTDFT Support for no current library Aug 27, 2026
@sebjulliand sebjulliand self-assigned this Aug 27, 2026
@sebjulliand
sebjulliand marked this pull request as draft August 27, 2026 07:22
@sebjulliand

sebjulliand commented Aug 27, 2026

Copy link
Copy Markdown
Member

Temporarily draft again: it will be more accurate to support a blank currentLibrary field, overall.
*CRTDFT will still be a valid current library value, but will be considered as a blank currentLibrary.

Signed-off-by: Seb Julliand <sebjulliand@gmail.com>
@sebjulliand
sebjulliand marked this pull request as ready for review August 27, 2026 08:34
@sebjulliand

sebjulliand commented Aug 27, 2026

Copy link
Copy Markdown
Member

@codefori/core it's ready for review again.
Having a blank/undefined currentLibrary in the config is now supported. Works like using *CRTDFT.

PR description has been updated accordingly.

@buzzia2001 buzzia2001 removed their assignment Aug 27, 2026
@buzzia2001

Copy link
Copy Markdown
Member Author

I can't submit an official review maybe because I've opened this pr... anyway @sebjulliand, some points:

  • debug/index.ts line 422: since now currentLibrary could be undefined don't we have to check before? or adding || '*CRTDFT' ?
  • what happens to actions related to IFS objects like crtdspf or something like that? CRTDSPF FILE(&CURLIB/&NAME) SRCFILE(&SRCFILE) RSTDSP(*NO) OPTION(*EVENTF) In this example, how works copying to using ifs path? /QSYS.LIB/*CURLIB.LIB/.... or /QSYS.LIB/*CRTDFT.LIB/... isn't a valid path...

Tomorrow I'll start testing it...

@sebjulliand

Copy link
Copy Markdown
Member

I opened a new PR #3430 so you can make a proper review (and start from a clean history).

debug/index.ts line 422: since now currentLibrary could be undefined don't we have to check before? or adding || '*CRTDFT' ?

Well spotted @buzzia2001 .

what happens to actions related to IFS objects like crtdspf or something like that? CRTDSPF FILE(&CURLIB/&NAME) SRCFILE(&SRCFILE) RSTDSP(*NO) OPTION(*EVENTF) In this example, how works copying to using ifs path? /QSYS.LIB/*CURLIB.LIB/.... or /QSYS.LIB/*CRTDFT.LIB/... isn't a valid path...

I'll check it out as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug A confirmed issue when something isn't working as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Current Library special value *CRTDFT not supported

4 participants